diff --git a/BUILDS.md b/BUILDS.md index 9173dbc41..7d1e4fb6d 100644 --- a/BUILDS.md +++ b/BUILDS.md @@ -136,6 +136,8 @@ | USE_GPS | - | - | - | - | - | - | - | | USE_HM10 | - | - | - | - | x | - | - | | USE_HRXL | - | - | - | - | x | - | - | +| USE_TASMOTA_SLAVE | - | - | - | - | - | - | - | +| USE_OPENTHERM | - | - | - | - | - | - | - | | | | | | | | | | | USE_NRF24 | - | - | - | - | - | - | - | | USE_MIBLE | - | - | - | - | - | - | - | @@ -149,11 +151,11 @@ | USE_TM1638 | - | - | - | - | x | - | - | | USE_HX711 | - | - | - | - | x | - | - | | USE_TX2x_WIND_SENSOR | - | - | - | - | - | - | - | +| USE_WINDMETER | - | - | - | - | - | - | - | | USE_RC_SWITCH | - | - | - | - | x | - | - | | USE_RF_SENSOR | - | - | - | - | x | - | - | AlectoV2 only | USE_HRE | - | - | - | - | x | - | - | | USE_A4988_STEPPER | - | - | - | - | - | - | - | -| USE_TASMOTA_SLAVE | - | - | - | - | - | - | - | Experimental | | | | | | | | | | Feature or Sensor | minimal | lite | tasmota | knx | sensors | ir | display | Remarks | USE_DISPLAY | - | - | - | - | - | - | x | @@ -167,3 +169,5 @@ | USE_DISPLAY_ILI9488 | - | - | - | - | - | - | - | | USE_DISPLAY_SSD1351 | - | - | - | - | - | - | - | | USE_DISPLAY_RA8876 | - | - | - | - | - | - | - | +| | | | | | | | | +| USE_WEBCAM | - | - | - | - | - | - | - | ESP32 only diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 2c7fc6f45..1b2ab6749 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -57,11 +57,13 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Breaking Change Device Groups multicast address and port (#8270) - Change PWM implementation to Arduino #7231 removing support for Core versions before 2.6.3 - Change default PWM Frequency to 223 Hz instead of 880 Hz for less interrupt pressure +- Change flash access removing support for any Core before 2.6.3 - Change HM-10 sensor type detection and add features (#7962) - Change light scheme 2,3,4 cycle time speed from 24,48,72,... seconds to 4,6,12,24,36,48,... seconds (#8034) - Change remove floating point libs from IRAM - Change remove MQTT Info messages on restart for DeepSleep Wake (#8044) - Change IRremoteESP8266 library updated to v2.7.6 +- Change HAss discovery by Federico Leoni (#8370) - Fix possible Relay toggle on (OTA) restart - Fix PWM flickering during wifi connection (#8046) - Fix Zigbee sending wrong Sat value with Hue emulation @@ -96,4 +98,6 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Add console command history (#7483, #8015) - Add quick wifi reconnect using saved AP parameters when ``SetOption56 0`` (#3189) - Add more accuracy to GPS NTP server (#8088) +- Add support for analog anemometer by Matteo Albinola (#8283) +- Add support for OpenTherm by Yuriy Sannikov (#8373) - Add experimental basic support for Tasmota on ESP32 based on work by Jörg Schüler-Maroldt diff --git a/lib/OpenTherm-0.9.0/LICENSE b/lib/OpenTherm-0.9.0/LICENSE new file mode 100644 index 000000000..42a9cdf66 --- /dev/null +++ b/lib/OpenTherm-0.9.0/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Ihor Melnyk + +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. diff --git a/lib/OpenTherm-0.9.0/README.md b/lib/OpenTherm-0.9.0/README.md new file mode 100644 index 000000000..9482c7403 --- /dev/null +++ b/lib/OpenTherm-0.9.0/README.md @@ -0,0 +1,65 @@ +# OpenTherm Arduino/ESP8266 Library + +This library provides implementation of OpenTherm protocol. + +OpenTherm Library is based on OpenTherm protocol specification v2.2 and works with all OpenTherm compatible boilers. Library can be easily installed into Arduino IDE and compiled for Arduino, ESP8266 and other similar controllers. + +OpenTherm protocol requires simple low voltage twowire connection to boiler, but voltage levels (7..15V) still much higher than Arduino/ESP8266 levels, which requires [OpenTherm Adapter](http://ihormelnyk.com/opentherm_adapter). + +This version of library uses interrupts to achieve better stability and synchronization with boiler. + +## Using OpenTherm Library you will be able: +- control your boiler remotely (get status, switch on/off heating/water heating, set water temperature and much more) +- make custom thermostat + +## Configuration and Usage: +```c +#include +``` +You have to choose 2 controller GPIO pins which will be used for communication and connected to [OpenTherm Adapter](http://ihormelnyk.com/opentherm_adapter). Controller(Arduino/ESP8266) input pin should support interrupts. +Controller output pin should be connected to OpenTherm Adapter input pin and vise versa. +```c +const int inPin = 2; +const int outPin = 3; +``` +Define OpenTherm class instance using constructor which accepts as arguments pin numbers: +```c +OpenTherm ot(inPin, outPin); +``` +Define interrupts handler function for specified above instance: +```c +void handleInterrupt() { + ot.handleInterrupt(); +} +``` +Use begin function to initialize OpenTherm instance, specify interrupts handler function as argument +```c +void setup() +{ + ot.begin(handleInterrupt); +} +``` +According to OpenTherm Protocol specification master (controller) must communicate at least every 1 sec. So lets make some requests in loop function: +```c +void loop() +{ + //Set/Get Boiler Status + ot.setBoilerStatus(enableCentralHeating, enableHotWater, enableCooling); + //Set Boiler Temperature to 64 degrees C + ot.setBoilerTemperature(64); + //Get Boiler Temperature + float temperature = ot.getBoilerTemperature(); + delay(1000); +} +``` + +In details [OpenTherm Library](http://ihormelnyk.com/opentherm_library) described [here](http://ihormelnyk.com/opentherm_library). + +## OpenTherm Adapter Schematic +![opentherm adapter schmetic](http://ihormelnyk.com/Content/Pages/opentherm_adapter/opentherm_adapter_schematic.png) + +## Arduino UNO Connection +![opentherm adapter arduino](http://ihormelnyk.com/Content/Pages/opentherm_adapter/opentherm_adapter_arduino_connection.png) + +## License +Copyright (c) 2018 [Ihor Melnyk](http://ihormelnyk.com). Licensed under the [MIT license](/LICENSE?raw=true). diff --git a/lib/OpenTherm-0.9.0/keywords.txt b/lib/OpenTherm-0.9.0/keywords.txt new file mode 100644 index 000000000..881d1da7d --- /dev/null +++ b/lib/OpenTherm-0.9.0/keywords.txt @@ -0,0 +1,40 @@ +####################################### +# Syntax Coloring Map For OpenTherm +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +OpenTherm KEYWORD1 +OpenThermStatus KEYWORD1 +OpenThermResponseStatus KEYWORD1 +OpenThermRequestType KEYWORD1 +OpenThermMessageID KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +begin KEYWORD2 +isReady KEYWORD2 +sendRequest KEYWORD2 +sendRequestAync KEYWORD2 +buildRequest KEYWORD2 +getLastResponseStatus KEYWORD2 +handleInterrupt KEYWORD2 +process KEYWORD2 +end KEYWORD2 +doSomething KEYWORD2 + +setBoilerStatus KEYWORD2 +setBoilerTemperature KEYWORD2 +getBoilerTemperature KEYWORD2 + +####################################### +# Instances (KEYWORD2) +####################################### + +####################################### +# Constants (LITERAL1) +####################################### \ No newline at end of file diff --git a/lib/OpenTherm-0.9.0/library.properties b/lib/OpenTherm-0.9.0/library.properties new file mode 100644 index 000000000..003b43eef --- /dev/null +++ b/lib/OpenTherm-0.9.0/library.properties @@ -0,0 +1,10 @@ +name=OpenTherm Library +version=0.9.0 +author=Ihor Melnyk +maintainer=Ihor Melnyk +sentence=OpenTherm Library for HVAC system control communication using Arduino and ESP8266 hardware. +paragraph=OpenTherm Library is based on OpenTherm protocol specification v2.2 and works with all OpenTherm compatible boilers. +category=Communication +url=https://github.com/ihormelnyk/opentherm_library +architectures=* +includes=OpenTherm.h diff --git a/lib/OpenTherm-0.9.0/src/OpenTherm.cpp b/lib/OpenTherm-0.9.0/src/OpenTherm.cpp new file mode 100644 index 000000000..a08608649 --- /dev/null +++ b/lib/OpenTherm-0.9.0/src/OpenTherm.cpp @@ -0,0 +1,410 @@ +/* +OpenTherm.cpp - OpenTherm Communication Library For Arduino, ESP8266 +Copyright 2018, Ihor Melnyk +*/ + +#include "OpenTherm.h" + +OpenTherm::OpenTherm(int inPin, int outPin, bool isSlave): + status(OpenThermStatus::NOT_INITIALIZED), + inPin(inPin), + outPin(outPin), + isSlave(isSlave), + response(0), + responseStatus(OpenThermResponseStatus::NONE), + responseTimestamp(0), + handleInterruptCallback(NULL), + processResponseCallback(NULL) +{ +} + +void OpenTherm::begin(void(*handleInterruptCallback)(void), void(*processResponseCallback)(unsigned long, int)) +{ + pinMode(inPin, INPUT); + pinMode(outPin, OUTPUT); + if (handleInterruptCallback != NULL) { + this->handleInterruptCallback = handleInterruptCallback; + attachInterrupt(digitalPinToInterrupt(inPin), handleInterruptCallback, CHANGE); + } + activateBoiler(); + status = OpenThermStatus::READY; + this->processResponseCallback = processResponseCallback; +} + +void OpenTherm::begin(void(*handleInterruptCallback)(void)) +{ + begin(handleInterruptCallback, NULL); +} + +bool ICACHE_RAM_ATTR OpenTherm::isReady() +{ + return status == OpenThermStatus::READY; +} + +int ICACHE_RAM_ATTR OpenTherm::readState() { + return digitalRead(inPin); +} + +void OpenTherm::setActiveState() { + digitalWrite(outPin, LOW); +} + +void OpenTherm::setIdleState() { + digitalWrite(outPin, HIGH); +} + +void OpenTherm::activateBoiler() { + setIdleState(); + delay(1000); +} + +void OpenTherm::sendBit(bool high) { + if (high) setActiveState(); else setIdleState(); + delayMicroseconds(500); + if (high) setIdleState(); else setActiveState(); + delayMicroseconds(500); +} + +bool OpenTherm::sendRequestAync(unsigned long request) +{ + //Serial.println("Request: " + String(request, HEX)); + noInterrupts(); + const bool ready = isReady(); + interrupts(); + + if (!ready) + return false; + + status = OpenThermStatus::REQUEST_SENDING; + response = 0; + responseStatus = OpenThermResponseStatus::NONE; + + sendBit(HIGH); //start bit + for (int i = 31; i >= 0; i--) { + sendBit(bitRead(request, i)); + } + sendBit(HIGH); //stop bit + setIdleState(); + + status = OpenThermStatus::RESPONSE_WAITING; + responseTimestamp = micros(); + return true; +} + +unsigned long OpenTherm::sendRequest(unsigned long request) +{ + if (!sendRequestAync(request)) return 0; + while (!isReady()) { + process(); + yield(); + } + return response; +} + +bool OpenTherm::sendResponse(unsigned long request) +{ + status = OpenThermStatus::REQUEST_SENDING; + response = 0; + responseStatus = OpenThermResponseStatus::NONE; + + sendBit(HIGH); //start bit + for (int i = 31; i >= 0; i--) { + sendBit(bitRead(request, i)); + } + sendBit(HIGH); //stop bit + setIdleState(); + status = OpenThermStatus::READY; + return true; +} + +OpenThermResponseStatus OpenTherm::getLastResponseStatus() +{ + return responseStatus; +} + +void ICACHE_RAM_ATTR OpenTherm::handleInterrupt() +{ + if (isReady()) + { + if (isSlave && readState() == HIGH) { + status = OpenThermStatus::RESPONSE_WAITING; + } + else { + return; + } + } + + unsigned long newTs = micros(); + if (status == OpenThermStatus::RESPONSE_WAITING) { + if (readState() == HIGH) { + status = OpenThermStatus::RESPONSE_START_BIT; + responseTimestamp = newTs; + } + else { + status = OpenThermStatus::RESPONSE_INVALID; + responseTimestamp = newTs; + } + } + else if (status == OpenThermStatus::RESPONSE_START_BIT) { + if ((newTs - responseTimestamp < 750) && readState() == LOW) { + status = OpenThermStatus::RESPONSE_RECEIVING; + responseTimestamp = newTs; + responseBitIndex = 0; + } + else { + status = OpenThermStatus::RESPONSE_INVALID; + responseTimestamp = newTs; + } + } + else if (status == OpenThermStatus::RESPONSE_RECEIVING) { + if ((newTs - responseTimestamp) > 750) { + if (responseBitIndex < 32) { + response = (response << 1) | !readState(); + responseTimestamp = newTs; + responseBitIndex++; + } + else { //stop bit + status = OpenThermStatus::RESPONSE_READY; + responseTimestamp = newTs; + } + } + } +} + +void OpenTherm::process() +{ + noInterrupts(); + OpenThermStatus st = status; + unsigned long ts = responseTimestamp; + interrupts(); + + if (st == OpenThermStatus::READY) return; + unsigned long newTs = micros(); + if (st != OpenThermStatus::NOT_INITIALIZED && (newTs - ts) > 1000000) { + status = OpenThermStatus::READY; + responseStatus = OpenThermResponseStatus::TIMEOUT; + if (processResponseCallback != NULL) { + processResponseCallback(response, responseStatus); + } + } + else if (st == OpenThermStatus::RESPONSE_INVALID) { + status = OpenThermStatus::DELAY; + responseStatus = OpenThermResponseStatus::INVALID; + if (processResponseCallback != NULL) { + processResponseCallback(response, responseStatus); + } + } + else if (st == OpenThermStatus::RESPONSE_READY) { + status = OpenThermStatus::DELAY; + responseStatus = (isSlave ? isValidRequest(response) : isValidResponse(response)) ? OpenThermResponseStatus::SUCCESS : OpenThermResponseStatus::INVALID; + if (processResponseCallback != NULL) { + processResponseCallback(response, responseStatus); + } + } + else if (st == OpenThermStatus::DELAY) { + if ((newTs - ts) > 100000) { + status = OpenThermStatus::READY; + } + } +} + +bool OpenTherm::parity(unsigned long frame) //odd parity +{ + byte p = 0; + while (frame > 0) + { + if (frame & 1) p++; + frame = frame >> 1; + } + return (p & 1); +} + +OpenThermMessageType OpenTherm::getMessageType(unsigned long message) +{ + OpenThermMessageType msg_type = static_cast((message >> 28) & 7); + return msg_type; +} + +OpenThermMessageID OpenTherm::getDataID(unsigned long frame) +{ + return (OpenThermMessageID)((frame >> 16) & 0xFF); +} + +unsigned long OpenTherm::buildRequest(OpenThermMessageType type, OpenThermMessageID id, unsigned int data) +{ + unsigned long request = data; + if (type == OpenThermMessageType::WRITE_DATA) { + request |= 1ul << 28; + } + request |= ((unsigned long)id) << 16; + if (OpenTherm::parity(request)) request |= (1ul << 31); + return request; +} + +unsigned long OpenTherm::buildResponse(OpenThermMessageType type, OpenThermMessageID id, unsigned int data) +{ + unsigned long response = data; + response |= type << 28; + response |= ((unsigned long)id) << 16; + if (OpenTherm::parity(response)) response |= (1ul << 31); + return response; +} + +bool OpenTherm::isValidResponse(unsigned long response) +{ + if (OpenTherm::parity(response)) return false; + byte msgType = (response << 1) >> 29; + return msgType == READ_ACK || msgType == WRITE_ACK; +} + +bool OpenTherm::isValidRequest(unsigned long request) +{ + if (OpenTherm::parity(request)) return false; + byte msgType = (request << 1) >> 29; + return msgType == READ_DATA || msgType == WRITE_DATA; +} + +void OpenTherm::end() { + if (this->handleInterruptCallback != NULL) { + detachInterrupt(digitalPinToInterrupt(inPin)); + } +} + +const char *OpenTherm::statusToString(OpenThermResponseStatus status) +{ + switch (status) { + case NONE: return "NONE"; + case SUCCESS: return "SUCCESS"; + case INVALID: return "INVALID"; + case TIMEOUT: return "TIMEOUT"; + default: return "UNKNOWN"; + } +} + +const char *OpenTherm::messageTypeToString(OpenThermMessageType message_type) +{ + switch (message_type) { + case READ_DATA: return "READ_DATA"; + case WRITE_DATA: return "WRITE_DATA"; + case INVALID_DATA: return "INVALID_DATA"; + case RESERVED: return "RESERVED"; + case READ_ACK: return "READ_ACK"; + case WRITE_ACK: return "WRITE_ACK"; + case DATA_INVALID: return "DATA_INVALID"; + case UNKNOWN_DATA_ID: return "UNKNOWN_DATA_ID"; + default: return "UNKNOWN"; + } +} + +//building requests + +unsigned long OpenTherm::buildSetBoilerStatusRequest(bool enableCentralHeating, bool enableHotWater, bool enableCooling, bool enableOutsideTemperatureCompensation, bool enableCentralHeating2) { + unsigned int data = enableCentralHeating | (enableHotWater << 1) | (enableCooling << 2) | (enableOutsideTemperatureCompensation << 3) | (enableCentralHeating2 << 4); + data <<= 8; + return buildRequest(OpenThermMessageType::READ_DATA, OpenThermMessageID::Status, data); +} + +unsigned long OpenTherm::buildSetBoilerTemperatureRequest(float temperature) { + unsigned int data = temperatureToData(temperature); + return buildRequest(OpenThermMessageType::WRITE_DATA, OpenThermMessageID::TSet, data); +} + +unsigned long OpenTherm::buildSetHotWaterTemperatureRequest(float temperature) { + unsigned int data = temperatureToData(temperature); + return buildRequest(OpenThermMessageType::WRITE_DATA, OpenThermMessageID::TdhwSet, data); +} + +unsigned long OpenTherm::buildGetBoilerTemperatureRequest() { + return buildRequest(OpenThermMessageType::READ_DATA, OpenThermMessageID::Tboiler, 0); +} + +unsigned long OpenTherm::buildSlaveConfigurationRequest() { + return buildRequest(OpenThermMessageType::READ_DATA, OpenThermMessageID::SConfigSMemberIDcode, 0); +} + +//parsing responses +bool OpenTherm::isFault(unsigned long response) { + return response & 0x1; +} + +bool OpenTherm::isCentralHeatingActive(unsigned long response) { + return response & 0x2; +} + +bool OpenTherm::isHotWaterActive(unsigned long response) { + return response & 0x4; +} + +bool OpenTherm::isFlameOn(unsigned long response) { + return response & 0x8; +} + +bool OpenTherm::isCoolingActive(unsigned long response) { + return response & 0x10; +} + +bool OpenTherm::isDiagnostic(unsigned long response) { + return response & 0x40; +} + +uint16_t OpenTherm::getUInt(const unsigned long response) { + const uint16_t u88 = response & 0xffff; + return u88; +} + +float OpenTherm::getFloat(const unsigned long response) { + const uint16_t u88 = getUInt(response); + const float f = (u88 & 0x8000) ? -(0x10000L - u88) / 256.0f : u88 / 256.0f; + return f; +} + +unsigned int OpenTherm::temperatureToData(float temperature) { + if (temperature < 0) temperature = 0; + if (temperature > 100) temperature = 100; + unsigned int data = (unsigned int)(temperature * 256); + return data; +} + +//basic requests + +unsigned long OpenTherm::setBoilerStatus(bool enableCentralHeating, bool enableHotWater, bool enableCooling, bool enableOutsideTemperatureCompensation, bool enableCentralHeating2) { + return sendRequest(buildSetBoilerStatusRequest(enableCentralHeating, enableHotWater, enableCooling, enableOutsideTemperatureCompensation, enableCentralHeating2)); +} + +bool OpenTherm::setBoilerTemperature(float temperature) { + unsigned long response = sendRequest(buildSetBoilerTemperatureRequest(temperature)); + return isValidResponse(response); +} + +bool OpenTherm::setHotWaterTemperature(float temperature) { + unsigned long response = sendRequest(buildSetHotWaterTemperatureRequest(temperature)); + return isValidResponse(response); +} + +float OpenTherm::getBoilerTemperature() { + unsigned long response = sendRequest(buildGetBoilerTemperatureRequest()); + return isValidResponse(response) ? getFloat(response) : 0; +} + +float OpenTherm::getReturnTemperature() { + unsigned long response = sendRequest(buildRequest(OpenThermRequestType::READ, OpenThermMessageID::Tret, 0)); + return isValidResponse(response) ? getFloat(response) : 0; +} + +float OpenTherm::getModulation() { + unsigned long response = sendRequest(buildRequest(OpenThermRequestType::READ, OpenThermMessageID::RelModLevel, 0)); + return isValidResponse(response) ? getFloat(response) : 0; +} + +float OpenTherm::getPressure() { + unsigned long response = sendRequest(buildRequest(OpenThermRequestType::READ, OpenThermMessageID::CHPressure, 0)); + return isValidResponse(response) ? getFloat(response) : 0; +} + +unsigned char OpenTherm::getFault() { + return ((sendRequest(buildRequest(OpenThermRequestType::READ, OpenThermMessageID::ASFflags, 0)) >> 8) & 0xff); +} + +unsigned long OpenTherm::getSlaveConfiguration() { + return sendRequest(buildSlaveConfigurationRequest()); +} \ No newline at end of file diff --git a/lib/OpenTherm-0.9.0/src/OpenTherm.h b/lib/OpenTherm-0.9.0/src/OpenTherm.h new file mode 100644 index 000000000..22bf965ad --- /dev/null +++ b/lib/OpenTherm-0.9.0/src/OpenTherm.h @@ -0,0 +1,193 @@ +/* +OpenTherm.h - OpenTherm Library for the ESP8266/Arduino platform +https://github.com/ihormelnyk/OpenTherm +http://ihormelnyk.com/pages/OpenTherm +Licensed under MIT license +Copyright 2018, Ihor Melnyk + +Frame Structure: +P MGS-TYPE SPARE DATA-ID DATA-VALUE +0 000 0000 00000000 00000000 00000000 +*/ + +#ifndef OpenTherm_h +#define OpenTherm_h + +#include +#include + +enum OpenThermResponseStatus { + NONE, + SUCCESS, + INVALID, + TIMEOUT +}; + + +enum OpenThermMessageType { + /* Master to Slave */ + READ_DATA = B000, + READ = READ_DATA, // for backwared compatibility + WRITE_DATA = B001, + WRITE = WRITE_DATA, // for backwared compatibility + INVALID_DATA = B010, + RESERVED = B011, + /* Slave to Master */ + READ_ACK = B100, + WRITE_ACK = B101, + DATA_INVALID = B110, + UNKNOWN_DATA_ID = B111 +}; + +typedef OpenThermMessageType OpenThermRequestType; // for backwared compatibility + +enum OpenThermMessageID { + Status, // flag8 / flag8 Master and Slave Status flags. + TSet, // f8.8 Control setpoint ie CH water temperature setpoint (°C) + MConfigMMemberIDcode, // flag8 / u8 Master Configuration Flags / Master MemberID Code + SConfigSMemberIDcode, // flag8 / u8 Slave Configuration Flags / Slave MemberID Code + Command, // u8 / u8 Remote Command + ASFflags, // / OEM-fault-code flag8 / u8 Application-specific fault flags and OEM fault code + RBPflags, // flag8 / flag8 Remote boiler parameter transfer-enable & read/write flags + CoolingControl, // f8.8 Cooling control signal (%) + TsetCH2, // f8.8 Control setpoint for 2e CH circuit (°C) + TrOverride, // f8.8 Remote override room setpoint + TSP, // u8 / u8 Number of Transparent-Slave-Parameters supported by slave + TSPindexTSPvalue, // u8 / u8 Index number / Value of referred-to transparent slave parameter. + FHBsize, // u8 / u8 Size of Fault-History-Buffer supported by slave + FHBindexFHBvalue, // u8 / u8 Index number / Value of referred-to fault-history buffer entry. + MaxRelModLevelSetting, // f8.8 Maximum relative modulation level setting (%) + MaxCapacityMinModLevel, // u8 / u8 Maximum boiler capacity (kW) / Minimum boiler modulation level(%) + TrSet, // f8.8 Room Setpoint (°C) + RelModLevel, // f8.8 Relative Modulation Level (%) + CHPressure, // f8.8 Water pressure in CH circuit (bar) + DHWFlowRate, // f8.8 Water flow rate in DHW circuit. (litres/minute) + DayTime, // special / u8 Day of Week and Time of Day + Date, // u8 / u8 Calendar date + Year, // u16 Calendar year + TrSetCH2, // f8.8 Room Setpoint for 2nd CH circuit (°C) + Tr, // f8.8 Room temperature (°C) + Tboiler, // f8.8 Boiler flow water temperature (°C) + Tdhw, // f8.8 DHW temperature (°C) + Toutside, // f8.8 Outside temperature (°C) + Tret, // f8.8 Return water temperature (°C) + Tstorage, // f8.8 Solar storage temperature (°C) + Tcollector, // f8.8 Solar collector temperature (°C) + TflowCH2, // f8.8 Flow water temperature CH2 circuit (°C) + Tdhw2, // f8.8 Domestic hot water temperature 2 (°C) + Texhaust, // s16 Boiler exhaust temperature (°C) + TdhwSetUBTdhwSetLB = 48, // s8 / s8 DHW setpoint upper & lower bounds for adjustment (°C) + MaxTSetUBMaxTSetLB, // s8 / s8 Max CH water setpoint upper & lower bounds for adjustment (°C) + HcratioUBHcratioLB, // s8 / s8 OTC heat curve ratio upper & lower bounds for adjustment + TdhwSet = 56, // f8.8 DHW setpoint (°C) (Remote parameter 1) + MaxTSet, // f8.8 Max CH water setpoint (°C) (Remote parameters 2) + Hcratio, // f8.8 OTC heat curve ratio (°C) (Remote parameter 3) + RemoteOverrideFunction = 100, // flag8 / - Function of manual and program changes in master and remote room setpoint. + OEMDiagnosticCode = 115, // u16 OEM-specific diagnostic/service code + BurnerStarts, // u16 Number of starts burner + CHPumpStarts, // u16 Number of starts CH pump + DHWPumpValveStarts, // u16 Number of starts DHW pump/valve + DHWBurnerStarts, // u16 Number of starts burner during DHW mode + BurnerOperationHours, // u16 Number of hours that burner is in operation (i.e. flame on) + CHPumpOperationHours, // u16 Number of hours that CH pump has been running + DHWPumpValveOperationHours, // u16 Number of hours that DHW pump has been running or DHW valve has been opened + DHWBurnerOperationHours, // u16 Number of hours that burner is in operation during DHW mode + OpenThermVersionMaster, // f8.8 The implemented version of the OpenTherm Protocol Specification in the master. + OpenThermVersionSlave, // f8.8 The implemented version of the OpenTherm Protocol Specification in the slave. + MasterVersion, // u8 / u8 Master product version number and type + SlaveVersion, // u8 / u8 Slave product version number and type +}; + +enum OpenThermStatus { + NOT_INITIALIZED, + READY, + DELAY, + REQUEST_SENDING, + RESPONSE_WAITING, + RESPONSE_START_BIT, + RESPONSE_RECEIVING, + RESPONSE_READY, + RESPONSE_INVALID +}; + +class OpenTherm +{ +public: + OpenTherm(int inPin = 4, int outPin = 5, bool isSlave = false); + volatile OpenThermStatus status; + void begin(void(*handleInterruptCallback)(void)); + void begin(void(*handleInterruptCallback)(void), void(*processResponseCallback)(unsigned long, int)); + bool isReady(); + unsigned long sendRequest(unsigned long request); + bool sendResponse(unsigned long request); + bool sendRequestAync(unsigned long request); + static unsigned long buildRequest(OpenThermMessageType type, OpenThermMessageID id, unsigned int data); + static unsigned long buildResponse(OpenThermMessageType type, OpenThermMessageID id, unsigned int data); + OpenThermResponseStatus getLastResponseStatus(); + const char *statusToString(OpenThermResponseStatus status); + void handleInterrupt(); + void process(); + void end(); + + static bool parity(unsigned long frame); + OpenThermMessageType getMessageType(unsigned long message); + OpenThermMessageID getDataID(unsigned long frame); + const char *messageTypeToString(OpenThermMessageType message_type); + bool isValidRequest(unsigned long request); + bool isValidResponse(unsigned long response); + + //requests + unsigned long buildSetBoilerStatusRequest(bool enableCentralHeating, bool enableHotWater = false, bool enableCooling = false, bool enableOutsideTemperatureCompensation = false, bool enableCentralHeating2 = false); + unsigned long buildSetBoilerTemperatureRequest(float temperature); + unsigned long buildGetBoilerTemperatureRequest(); + unsigned long buildSetHotWaterTemperatureRequest(float temperature); + unsigned long buildSlaveConfigurationRequest(); + + + //responses + static bool isFault(unsigned long response); + static bool isCentralHeatingActive(unsigned long response); + static bool isHotWaterActive(unsigned long response); + static bool isFlameOn(unsigned long response); + static bool isCoolingActive(unsigned long response); + static bool isDiagnostic(unsigned long response); + static uint16_t getUInt(const unsigned long response); + static float getFloat(const unsigned long response); + static unsigned int temperatureToData(float temperature); + + //basic requests + unsigned long setBoilerStatus(bool enableCentralHeating, bool enableHotWater = false, bool enableCooling = false, bool enableOutsideTemperatureCompensation = false, bool enableCentralHeating2 = false); + bool setBoilerTemperature(float temperature); + bool setHotWaterTemperature(float temperature); + float getBoilerTemperature(); + float getReturnTemperature(); + float getModulation(); + float getPressure(); + unsigned char getFault(); + unsigned long getSlaveConfiguration(); + +private: + const int inPin; + const int outPin; + const bool isSlave; + + volatile unsigned long response; + volatile OpenThermResponseStatus responseStatus; + volatile unsigned long responseTimestamp; + volatile byte responseBitIndex; + + int readState(); + void setActiveState(); + void setIdleState(); + void activateBoiler(); + + void sendBit(bool high); + void(*handleInterruptCallback)(); + void(*processResponseCallback)(unsigned long, int); +}; + +#ifndef ICACHE_RAM_ATTR +#define ICACHE_RAM_ATTR +#endif + +#endif // OpenTherm_h \ No newline at end of file diff --git a/pio/override_copy.py b/pio/override_copy.py new file mode 100644 index 000000000..1cb6c991b --- /dev/null +++ b/pio/override_copy.py @@ -0,0 +1,9 @@ +Import('env') +import os +import shutil + +# copy tasmota/user_config_override_sample.h to tasmota/user_config_override.h +if os.path.isfile("tasmota/user_config_override.h"): + print ("*** use provided user_config_override.h as planned ***") +else: + shutil.copy("tasmota/user_config_override_sample.h", "tasmota/user_config_override.h") diff --git a/platformio.ini b/platformio.ini index 7688d3974..618e7e572 100644 --- a/platformio.ini +++ b/platformio.ini @@ -8,17 +8,19 @@ ; http://docs.platformio.org/en/stable/projectconf.html [platformio] +description = Provide ESP8266 based devices with Web, MQTT and OTA firmware src_dir = tasmota build_dir = .pioenvs +workspace_dir = .pioenvs build_cache_dir = .cache extra_configs = platformio_tasmota_env.ini platformio_override.ini ; *** Build/upload environment -default_envs = +default_envs = ; *** Uncomment by deleting ";" in the line(s) below to select version(s) ; tasmota -; tasmota-ircustom +; tasmota-ircustom ; tasmota-minimal ; tasmota-lite ; tasmota-knx @@ -64,11 +66,8 @@ platform_packages = ${core_active.platform_packages} build_flags = ${core_active.build_flags} ; ********************************************************************* -; *** Uncomment, by deleting ";" in line below, to use custom settings from file user_config_override.h -; -DUSE_CONFIG_OVERRIDE -; -; *** alternatively can be done in: platformio_override.ini -; *** See example: platformio_override_sample.ini +; *** Use custom settings from file user_config_override.h + -DUSE_CONFIG_OVERRIDE ; ********************************************************************* ; *** Fix espressif8266@1.7.0 induced undesired all warnings @@ -86,6 +85,7 @@ extra_scripts = ${scripts_defaults.extra_scripts} extra_scripts = pio/strip-floats.py pio/name-firmware.py pio/gzip-firmware.py + pio/override_copy.py [esp_defaults] build_flags = -D_IR_ENABLE_DEFAULT_=false diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index f793e9bd8..7bbbb9165 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -9,7 +9,10 @@ ### 8.2.0.6 20200501 - Add experimental basic support for Tasmota on ESP32 based on work by Jörg Schüler-Maroldt -- Change PWM updated to latest Arduino Core #7213 +- Add support for analog anemometer by Matteo Albinola (#8283) +- Add support for OpenTherm by Yuriy Sannikov (#8373) +- Change flash access removing support for any Core before 2.6.3 +- Change HAss discovery by Federico Leoni (#8370) ### 8.2.0.5 20200425 diff --git a/tasmota/i18n.h b/tasmota/i18n.h index ab064f630..491c0e77c 100644 --- a/tasmota/i18n.h +++ b/tasmota/i18n.h @@ -558,6 +558,7 @@ #define D_CMND_SHUTTER_RELAY "Relay" #define D_CMND_SHUTTER_SETHALFWAY "SetHalfway" #define D_CMND_SHUTTER_SETCLOSE "SetClose" +#define D_CMND_SHUTTER_SETOPEN "SetOpen" #define D_CMND_SHUTTER_INVERT "Invert" #define D_CMND_SHUTTER_CLIBRATION "Calibration" #define D_CMND_SHUTTER_MOTORDELAY "MotorDelay" diff --git a/tasmota/language/bg_BG.h b/tasmota/language/bg_BG.h index 58bc8fa70..14bf6f698 100644 --- a/tasmota/language/bg_BG.h +++ b/tasmota/language/bg_BG.h @@ -482,6 +482,14 @@ #define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter #define D_PARTICALS_BEYOND "Частици" +// xsns_27_apds9960.ino +#define D_GESTURE "Жест" +#define D_COLOR_RED "Red" +#define D_COLOR_GREEN "Грийн" +#define D_COLOR_BLUE "син" +#define D_CCT "CCT" +#define D_PROXIMITY "близост" + // xsns_32_mpu6050.ino #define D_AX_AXIS "Ускорение - ос X" #define D_AY_AXIS "Ускорение - ос Y" @@ -666,6 +674,7 @@ #define D_SENSOR_HRXL_RX "HRXL Rx" #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" +#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" @@ -785,4 +794,8 @@ #define D_AS3935_CAL_FAIL "calibration failed" #define D_AS3935_CAL_OK "calibration set to:" +//xsns_68_opentherm.ino +#define D_SENSOR_BOILER_OT_RX "OpenTherm RX" +#define D_SENSOR_BOILER_OT_TX "OpenTherm TX" + #endif // _LANGUAGE_BG_BG_H_ diff --git a/tasmota/language/cs_CZ.h b/tasmota/language/cs_CZ.h index 0d3b143c8..6da814036 100644 --- a/tasmota/language/cs_CZ.h +++ b/tasmota/language/cs_CZ.h @@ -482,6 +482,14 @@ #define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter #define D_PARTICALS_BEYOND "částic" +// xsns_27_apds9960.ino +#define D_GESTURE "Gesto" +#define D_COLOR_RED "Červená" +#define D_COLOR_GREEN "Zelená" +#define D_COLOR_BLUE "Modrá" +#define D_CCT "CCT" +#define D_PROXIMITY "Blízkost" + // xsns_32_mpu6050.ino #define D_AX_AXIS "Accel. osa-X" #define D_AY_AXIS "Accel. osa-Y" @@ -666,6 +674,7 @@ #define D_SENSOR_HRXL_RX "HRXL Rx" #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" +#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" @@ -785,4 +794,8 @@ #define D_AS3935_CAL_FAIL "calibration failed" #define D_AS3935_CAL_OK "calibration set to:" +//xsns_68_opentherm.ino +#define D_SENSOR_BOILER_OT_RX "OpenTherm RX" +#define D_SENSOR_BOILER_OT_TX "OpenTherm TX" + #endif // _LANGUAGE_CS_CZ_H_ diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h index d10e1c599..63d38dc58 100644 --- a/tasmota/language/de_DE.h +++ b/tasmota/language/de_DE.h @@ -482,6 +482,14 @@ #define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter #define D_PARTICALS_BEYOND "Partikel" +// xsns_27_apds9960.ino +#define D_GESTURE "Geste" +#define D_COLOR_RED "Rot" +#define D_COLOR_GREEN "Grün" +#define D_COLOR_BLUE "Blau" +#define D_CCT "CCT" +#define D_PROXIMITY "Nähe" + // xsns_32_mpu6050.ino #define D_AX_AXIS "Beschl. X-Achse" #define D_AY_AXIS "Beschl. Y-Achse" @@ -666,6 +674,7 @@ #define D_SENSOR_HRXL_RX "HRXL Rx" #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" +#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" @@ -785,4 +794,8 @@ #define D_AS3935_CAL_FAIL "Kalibrierung fehlerhaft" #define D_AS3935_CAL_OK "Cap gesetzt auf:" +//xsns_68_opentherm.ino +#define D_SENSOR_BOILER_OT_RX "OpenTherm RX" +#define D_SENSOR_BOILER_OT_TX "OpenTherm TX" + #endif // _LANGUAGE_DE_DE_H_ diff --git a/tasmota/language/el_GR.h b/tasmota/language/el_GR.h index bf9390eee..d89a8c5ce 100644 --- a/tasmota/language/el_GR.h +++ b/tasmota/language/el_GR.h @@ -482,6 +482,14 @@ #define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter #define D_PARTICALS_BEYOND "Particals" +// xsns_27_apds9960.ino +#define D_GESTURE "Χειρονομία" +#define D_COLOR_RED "Κόκκινο" +#define D_COLOR_GREEN "Πράσινο" +#define D_COLOR_BLUE "Μπλε" +#define D_CCT "CCT" +#define D_PROXIMITY "Εγγύτητα" + // xsns_32_mpu6050.ino #define D_AX_AXIS "Accel. X-Axis" #define D_AY_AXIS "Accel. Y-Axis" @@ -666,6 +674,7 @@ #define D_SENSOR_HRXL_RX "HRXL Rx" #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" +#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" @@ -785,4 +794,8 @@ #define D_AS3935_CAL_FAIL "calibration failed" #define D_AS3935_CAL_OK "calibration set to:" +//xsns_68_opentherm.ino +#define D_SENSOR_BOILER_OT_RX "OpenTherm RX" +#define D_SENSOR_BOILER_OT_TX "OpenTherm TX" + #endif // _LANGUAGE_EL_GR_H_ diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h index 44975b867..dcc945c80 100644 --- a/tasmota/language/en_GB.h +++ b/tasmota/language/en_GB.h @@ -482,6 +482,14 @@ #define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter #define D_PARTICALS_BEYOND "Particles" +// 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_CCT "CCT" +#define D_PROXIMITY "Proximity" + // xsns_32_mpu6050.ino #define D_AX_AXIS "Accel. X-Axis" #define D_AY_AXIS "Accel. Y-Axis" @@ -666,6 +674,7 @@ #define D_SENSOR_HRXL_RX "HRXL Rx" #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" +#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" @@ -687,6 +696,7 @@ #define D_UNIT_GALLONS "gal" #define D_UNIT_GALLONS_PER_MIN "g/m" #define D_UNIT_INCREMENTS "inc" +#define D_UNIT_KELVIN "°K" #define D_UNIT_KILOMETER "km" #define D_UNIT_KILOGRAM "kg" #define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h" @@ -785,4 +795,8 @@ #define D_AS3935_CAL_FAIL "calibration failed" #define D_AS3935_CAL_OK "calibration set to:" +//xsns_68_opentherm.ino +#define D_SENSOR_BOILER_OT_RX "OpenTherm RX" +#define D_SENSOR_BOILER_OT_TX "OpenTherm TX" + #endif // _LANGUAGE_EN_GB_H_ diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h index 30ae8044f..19cbf5e66 100644 --- a/tasmota/language/es_ES.h +++ b/tasmota/language/es_ES.h @@ -482,6 +482,14 @@ #define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter #define D_PARTICALS_BEYOND "Partículas" +// xsns_27_apds9960.ino +#define D_GESTURE "Gesto" +#define D_COLOR_RED "Rojo" +#define D_COLOR_GREEN "Verde" +#define D_COLOR_BLUE "Azul" +#define D_CCT "CCT" +#define D_PROXIMITY "Proximidad" + // xsns_32_mpu6050.ino #define D_AX_AXIS "Accel. X-Axis" #define D_AY_AXIS "Accel. Y-Axis" @@ -666,6 +674,7 @@ #define D_SENSOR_HRXL_RX "HRXL Rx" #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" +#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" @@ -785,4 +794,8 @@ #define D_AS3935_CAL_FAIL "calibration failed" #define D_AS3935_CAL_OK "calibration set to:" +//xsns_68_opentherm.ino +#define D_SENSOR_BOILER_OT_RX "OpenTherm RX" +#define D_SENSOR_BOILER_OT_TX "OpenTherm TX" + #endif // _LANGUAGE_ES_ES_H_ diff --git a/tasmota/language/fr_FR.h b/tasmota/language/fr_FR.h index 516606a0c..44e1d1020 100644 --- a/tasmota/language/fr_FR.h +++ b/tasmota/language/fr_FR.h @@ -482,6 +482,14 @@ #define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter #define D_PARTICALS_BEYOND "Particules" +// xsns_27_apds9960.ino +#define D_GESTURE "Geste" +#define D_COLOR_RED "Rouge" +#define D_COLOR_GREEN "Vert" +#define D_COLOR_BLUE "Bleu" +#define D_CCT "CCT" +#define D_PROXIMITY "Proximité" + // xsns_32_mpu6050.ino #define D_AX_AXIS "Accél. Axe-X" #define D_AY_AXIS "Accél. Axe-Y" @@ -503,7 +511,7 @@ #define D_CALIBRATE "Étalonner" #define D_CALIBRATION "Étalonnage" -//xsns_35_TX20.ino +// xsns_35_TX20.ino #define D_TX20_WIND_DIRECTION "Direction du vent" #define D_TX20_WIND_SPEED "Vitesse du vent" #define D_TX20_WIND_SPEED_MIN "Vitesse Min" @@ -666,6 +674,7 @@ #define D_SENSOR_HRXL_RX "HRXL Rx" #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" +#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" @@ -785,4 +794,8 @@ #define D_AS3935_CAL_FAIL "calibration failed" #define D_AS3935_CAL_OK "calibration set to:" +//xsns_68_opentherm.ino +#define D_SENSOR_BOILER_OT_RX "OpenTherm RX" +#define D_SENSOR_BOILER_OT_TX "OpenTherm TX" + #endif // _LANGUAGE_FR_FR_H_ diff --git a/tasmota/language/he_HE.h b/tasmota/language/he_HE.h index 9d266eb9d..058789eb3 100644 --- a/tasmota/language/he_HE.h +++ b/tasmota/language/he_HE.h @@ -482,6 +482,14 @@ #define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter #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_CCT "CCT" +#define D_PROXIMITY "Proximity" + // xsns_32_mpu6050.ino #define D_AX_AXIS "Accel. X-Axis" #define D_AY_AXIS "Accel. Y-Axis" @@ -666,6 +674,7 @@ #define D_SENSOR_HRXL_RX "HRXL Rx" #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" +#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" @@ -785,4 +794,8 @@ #define D_AS3935_CAL_FAIL "calibration failed" #define D_AS3935_CAL_OK "calibration set to:" +//xsns_68_opentherm.ino +#define D_SENSOR_BOILER_OT_RX "OpenTherm RX" +#define D_SENSOR_BOILER_OT_TX "OpenTherm TX" + #endif // _LANGUAGE_HE_HE_H_ diff --git a/tasmota/language/hu_HU.h b/tasmota/language/hu_HU.h index 5e69bedfb..cad66ebee 100644 --- a/tasmota/language/hu_HU.h +++ b/tasmota/language/hu_HU.h @@ -482,6 +482,14 @@ #define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter #define D_PARTICALS_BEYOND "Részecskék" +// xsns_27_apds9960.ino +#define D_GESTURE "Gesztus" +#define D_COLOR_RED "Red" +#define D_COLOR_GREEN "Green" +#define D_COLOR_BLUE "Blue" +#define D_CCT "CCT" +#define D_PROXIMITY "közelség" + // xsns_32_mpu6050.ino #define D_AX_AXIS "Gyorsulásm. X-tengely" #define D_AY_AXIS "Gyorsulásm. Y-tengely" @@ -666,6 +674,7 @@ #define D_SENSOR_HRXL_RX "HRXL Rx" #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" +#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" @@ -785,4 +794,8 @@ #define D_AS3935_CAL_FAIL "calibration failed" #define D_AS3935_CAL_OK "calibration set to:" +//xsns_68_opentherm.ino +#define D_SENSOR_BOILER_OT_RX "OpenTherm RX" +#define D_SENSOR_BOILER_OT_TX "OpenTherm TX" + #endif // _LANGUAGE_HU_HU_H_ diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index a434222bf..5c6dcae10 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -62,7 +62,7 @@ #define D_BRIGHTLIGHT "Luminoso" #define D_BSSID "BSSId" #define D_BUTTON "Pulsante" -#define D_BY "da" // Written by me +#define D_BY "di" // Written by me #define D_BYTES "Byte" #define D_CELSIUS "Celsius" #define D_CHANNEL "Canale" @@ -482,6 +482,14 @@ #define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter #define D_PARTICALS_BEYOND "Particelle" +// xsns_27_apds9960.ino +#define D_GESTURE "Gesto" +#define D_COLOR_RED "Rosso" +#define D_COLOR_GREEN "Verde" +#define D_COLOR_BLUE "Blu" +#define D_CCT "CCT" +#define D_PROXIMITY "Vicinanza" + // xsns_32_mpu6050.ino #define D_AX_AXIS "Accelerazione asse X" #define D_AY_AXIS "Accelerazione asse Y" @@ -666,6 +674,7 @@ #define D_SENSOR_HRXL_RX "HRXL - RX" #define D_SENSOR_ELECTRIQ_MOODL "MOODL - TX" #define D_SENSOR_AS3935 "AS3935" +#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" @@ -763,26 +772,30 @@ #define D_SCRIPT_UPLOAD_FILES "Upload file" //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_GAIN "guadagno:" +#define D_AS3935_ENERGY "energia:" +#define D_AS3935_DISTANCE "distanza:" +#define D_AS3935_DISTURBER "disturbatore:" #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 "apross.:" +#define D_AS3935_AWAY "lontano" +#define D_AS3935_LIGHT "illuminazione" +#define D_AS3935_OUT "illuminazione fuori intervallo" +#define D_AS3935_NOT "distanza non determinata" +#define D_AS3935_ABOVE "illuminazione ambientale" +#define D_AS3935_NOISE "rilevato rumore" +#define D_AS3935_DISTDET "rilevato disturbatore" +#define D_AS3935_INTNOEV "Interrupt senza evento!" +#define D_AS3935_NOMESS "in ascolto..." +#define D_AS3935_ON "ON" +#define D_AS3935_OFF "OFF" +#define D_AS3935_INDOORS "Interno" +#define D_AS3935_OUTDOORS "Esterno" +#define D_AS3935_CAL_FAIL "calibrazione fallita" +#define D_AS3935_CAL_OK "calibrazione impostata a:" + +//xsns_68_opentherm.ino +#define D_SENSOR_BOILER_OT_RX "OpenTherm RX" +#define D_SENSOR_BOILER_OT_TX "OpenTherm TX" #endif // _LANGUAGE_IT_IT_H_ diff --git a/tasmota/language/ko_KO.h b/tasmota/language/ko_KO.h index f1a4e9427..7a84823ff 100644 --- a/tasmota/language/ko_KO.h +++ b/tasmota/language/ko_KO.h @@ -482,6 +482,14 @@ #define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter #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_CCT "CCT" +#define D_PROXIMITY "Proximity" + // xsns_32_mpu6050.ino #define D_AX_AXIS "Accel. X-Axis" #define D_AY_AXIS "Accel. Y-Axis" @@ -666,6 +674,7 @@ #define D_SENSOR_HRXL_RX "HRXL Rx" #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" +#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" @@ -785,4 +794,8 @@ #define D_AS3935_CAL_FAIL "calibration failed" #define D_AS3935_CAL_OK "calibration set to:" +//xsns_68_opentherm.ino +#define D_SENSOR_BOILER_OT_RX "OpenTherm RX" +#define D_SENSOR_BOILER_OT_TX "OpenTherm TX" + #endif // _LANGUAGE_KO_KO_H_ diff --git a/tasmota/language/nl_NL.h b/tasmota/language/nl_NL.h index 3b257470f..d5922cb6a 100644 --- a/tasmota/language/nl_NL.h +++ b/tasmota/language/nl_NL.h @@ -482,6 +482,14 @@ #define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter #define D_PARTICALS_BEYOND "Stofdeeltjes" +// 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_CCT "CCT" +#define D_PROXIMITY "Proximity" + // xsns_32_mpu6050.ino #define D_AX_AXIS "Versn. X-as" #define D_AY_AXIS "Versn. Y-as" @@ -666,6 +674,7 @@ #define D_SENSOR_HRXL_RX "HRXL Rx" #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" +#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" @@ -785,4 +794,8 @@ #define D_AS3935_CAL_FAIL "calibration failed" #define D_AS3935_CAL_OK "calibration set to:" +//xsns_68_opentherm.ino +#define D_SENSOR_BOILER_OT_RX "OpenTherm RX" +#define D_SENSOR_BOILER_OT_TX "OpenTherm TX" + #endif // _LANGUAGE_NL_NL_H_ diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h index 3dfa6be1d..f50d22de4 100644 --- a/tasmota/language/pl_PL.h +++ b/tasmota/language/pl_PL.h @@ -482,6 +482,14 @@ #define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter #define D_PARTICALS_BEYOND "Cząstki" +// 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_CCT "CCT" +#define D_PROXIMITY "Proximity" + // xsns_32_mpu6050.ino #define D_AX_AXIS "Accel. X-Axis" #define D_AY_AXIS "Accel. Y-Axis" @@ -666,6 +674,7 @@ #define D_SENSOR_HRXL_RX "HRXL Rx" #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" +#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" @@ -785,4 +794,8 @@ #define D_AS3935_CAL_FAIL "calibration failed" #define D_AS3935_CAL_OK "calibration set to:" +//xsns_68_opentherm.ino +#define D_SENSOR_BOILER_OT_RX "OpenTherm RX" +#define D_SENSOR_BOILER_OT_TX "OpenTherm TX" + #endif // _LANGUAGE_PL_PL_D_H_ diff --git a/tasmota/language/pt_BR.h b/tasmota/language/pt_BR.h index b4c21967a..dab2a3a54 100644 --- a/tasmota/language/pt_BR.h +++ b/tasmota/language/pt_BR.h @@ -482,6 +482,14 @@ #define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter #define D_PARTICALS_BEYOND "Partículas" +// 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_CCT "CCT" +#define D_PROXIMITY "Proximity" + // xsns_32_mpu6050.ino #define D_AX_AXIS "Accel. X-Axis" #define D_AY_AXIS "Accel. Y-Axis" @@ -666,6 +674,7 @@ #define D_SENSOR_HRXL_RX "HRXL Rx" #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" +#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" @@ -785,4 +794,8 @@ #define D_AS3935_CAL_FAIL "calibration failed" #define D_AS3935_CAL_OK "calibration set to:" +//xsns_68_opentherm.ino +#define D_SENSOR_BOILER_OT_RX "OpenTherm RX" +#define D_SENSOR_BOILER_OT_TX "OpenTherm TX" + #endif // _LANGUAGE_PT_BR_H_ diff --git a/tasmota/language/pt_PT.h b/tasmota/language/pt_PT.h index e2a1be9e8..e056245c1 100644 --- a/tasmota/language/pt_PT.h +++ b/tasmota/language/pt_PT.h @@ -482,6 +482,14 @@ #define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter #define D_PARTICALS_BEYOND "Partículas" +// 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_CCT "CCT" +#define D_PROXIMITY "Proximity" + // xsns_32_mpu6050.ino #define D_AX_AXIS "Accel. X-Axis" #define D_AY_AXIS "Accel. Y-Axis" @@ -666,6 +674,7 @@ #define D_SENSOR_HRXL_RX "HRXL Rx" #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" +#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" @@ -785,4 +794,8 @@ #define D_AS3935_CAL_FAIL "calibration failed" #define D_AS3935_CAL_OK "calibration set to:" +//xsns_68_opentherm.ino +#define D_SENSOR_BOILER_OT_RX "OpenTherm RX" +#define D_SENSOR_BOILER_OT_TX "OpenTherm TX" + #endif // _LANGUAGE_PT_PT_H_ diff --git a/tasmota/language/ro_RO.h b/tasmota/language/ro_RO.h index fbf8cd695..83bb05575 100644 --- a/tasmota/language/ro_RO.h +++ b/tasmota/language/ro_RO.h @@ -482,6 +482,14 @@ #define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter #define D_PARTICALS_BEYOND "Particule" +// 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_CCT "CCT" +#define D_PROXIMITY "Proximity" + // xsns_32_mpu6050.ino #define D_AX_AXIS "Accel.Axa-X" #define D_AY_AXIS "Accel.Axa-Y" @@ -666,6 +674,7 @@ #define D_SENSOR_HRXL_RX "HRXL Rx" #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" +#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" @@ -785,4 +794,8 @@ #define D_AS3935_CAL_FAIL "calibration failed" #define D_AS3935_CAL_OK "calibration set to:" +//xsns_68_opentherm.ino +#define D_SENSOR_BOILER_OT_RX "OpenTherm RX" +#define D_SENSOR_BOILER_OT_TX "OpenTherm TX" + #endif // _LANGUAGE_RO_RO_H_ diff --git a/tasmota/language/ru_RU.h b/tasmota/language/ru_RU.h index 4a86c5fc9..93cbf2c72 100644 --- a/tasmota/language/ru_RU.h +++ b/tasmota/language/ru_RU.h @@ -482,6 +482,14 @@ #define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter #define D_PARTICALS_BEYOND "Particals" +// 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_CCT "CCT" +#define D_PROXIMITY "Proximity" + // xsns_32_mpu6050.ino #define D_AX_AXIS "Accel. X-Axis" #define D_AY_AXIS "Accel. Y-Axis" @@ -666,6 +674,7 @@ #define D_SENSOR_HRXL_RX "HRXL Rx" #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" +#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" @@ -785,4 +794,8 @@ #define D_AS3935_CAL_FAIL "calibration failed" #define D_AS3935_CAL_OK "calibration set to:" +//xsns_68_opentherm.ino +#define D_SENSOR_BOILER_OT_RX "OpenTherm RX" +#define D_SENSOR_BOILER_OT_TX "OpenTherm TX" + #endif // _LANGUAGE_RU_RU_H_ diff --git a/tasmota/language/sk_SK.h b/tasmota/language/sk_SK.h index bfb1abf4a..0a6415c16 100644 --- a/tasmota/language/sk_SK.h +++ b/tasmota/language/sk_SK.h @@ -482,6 +482,14 @@ #define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter #define D_PARTICALS_BEYOND "častíc" +// 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_CCT "CCT" +#define D_PROXIMITY "Proximity" + // xsns_32_mpu6050.ino #define D_AX_AXIS "Accel. os-X" #define D_AY_AXIS "Accel. os-Y" @@ -666,6 +674,7 @@ #define D_SENSOR_HRXL_RX "HRXL Rx" #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" +#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" @@ -785,4 +794,8 @@ #define D_AS3935_CAL_FAIL "calibration failed" #define D_AS3935_CAL_OK "calibration set to:" +//xsns_68_opentherm.ino +#define D_SENSOR_BOILER_OT_RX "OpenTherm RX" +#define D_SENSOR_BOILER_OT_TX "OpenTherm TX" + #endif // _LANGUAGE_SK_SK_H_ diff --git a/tasmota/language/sv_SE.h b/tasmota/language/sv_SE.h index 6753c78f5..438bcd3c1 100644 --- a/tasmota/language/sv_SE.h +++ b/tasmota/language/sv_SE.h @@ -482,6 +482,14 @@ #define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter #define D_PARTICALS_BEYOND "Partiklar" +// 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_CCT "CCT" +#define D_PROXIMITY "Proximity" + // xsns_32_mpu6050.ino #define D_AX_AXIS "Accel. X-Axel" #define D_AY_AXIS "Accel. Y-Axel" @@ -666,6 +674,7 @@ #define D_SENSOR_HRXL_RX "HRXL Rx" #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" +#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" @@ -785,4 +794,8 @@ #define D_AS3935_CAL_FAIL "calibration failed" #define D_AS3935_CAL_OK "calibration set to:" +//xsns_68_opentherm.ino +#define D_SENSOR_BOILER_OT_RX "OpenTherm RX" +#define D_SENSOR_BOILER_OT_TX "OpenTherm TX" + #endif // _LANGUAGE_SV_SE_H_ diff --git a/tasmota/language/tr_TR.h b/tasmota/language/tr_TR.h index d82f10f5a..740b92774 100644 --- a/tasmota/language/tr_TR.h +++ b/tasmota/language/tr_TR.h @@ -482,6 +482,14 @@ #define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter #define D_PARTICALS_BEYOND "Particals" +// 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_CCT "CCT" +#define D_PROXIMITY "Proximity" + // xsns_32_mpu6050.ino #define D_AX_AXIS "Accel. X-Axis" #define D_AY_AXIS "Accel. Y-Axis" @@ -666,6 +674,7 @@ #define D_SENSOR_HRXL_RX "HRXL Rx" #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" +#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" @@ -785,4 +794,8 @@ #define D_AS3935_CAL_FAIL "calibration failed" #define D_AS3935_CAL_OK "calibration set to:" +//xsns_68_opentherm.ino +#define D_SENSOR_BOILER_OT_RX "OpenTherm RX" +#define D_SENSOR_BOILER_OT_TX "OpenTherm TX" + #endif // _LANGUAGE_TR_TR_H_ diff --git a/tasmota/language/uk_UA.h b/tasmota/language/uk_UA.h index b5ba3ebae..bf0377e7b 100644 --- a/tasmota/language/uk_UA.h +++ b/tasmota/language/uk_UA.h @@ -482,6 +482,14 @@ #define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter #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_CCT "CCT" +#define D_PROXIMITY "Proximity" + // xsns_32_mpu6050.ino #define D_AX_AXIS "Приск. Вісь-X" #define D_AY_AXIS "Приск. Вісь-Y" @@ -666,6 +674,7 @@ #define D_SENSOR_HRXL_RX "HRXL Rx" #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" +#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" @@ -785,4 +794,8 @@ #define D_AS3935_CAL_FAIL "calibration failed" #define D_AS3935_CAL_OK "calibration set to:" +//xsns_68_opentherm.ino +#define D_SENSOR_BOILER_OT_RX "OpenTherm RX" +#define D_SENSOR_BOILER_OT_TX "OpenTherm TX" + #endif // _LANGUAGE_UK_UA_H_ diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h index e269d8f57..49e7b8592 100644 --- a/tasmota/language/zh_CN.h +++ b/tasmota/language/zh_CN.h @@ -482,6 +482,14 @@ #define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter #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_CCT "CCT" +#define D_PROXIMITY "Proximity" + // xsns_32_mpu6050.ino #define D_AX_AXIS "加速度计X轴分量" #define D_AY_AXIS "加速度计Y轴分量" @@ -666,6 +674,7 @@ #define D_SENSOR_HRXL_RX "HRXL Rx" #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" +#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" @@ -785,4 +794,8 @@ #define D_AS3935_CAL_FAIL "calibration failed" #define D_AS3935_CAL_OK "calibration set to:" +//xsns_68_opentherm.ino +#define D_SENSOR_BOILER_OT_RX "OpenTherm RX" +#define D_SENSOR_BOILER_OT_TX "OpenTherm TX" + #endif // _LANGUAGE_ZH_CN_H_ diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h index 28baa4920..7f92495a4 100644 --- a/tasmota/language/zh_TW.h +++ b/tasmota/language/zh_TW.h @@ -482,6 +482,14 @@ #define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter #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_CCT "CCT" +#define D_PROXIMITY "Proximity" + // xsns_32_mpu6050.ino #define D_AX_AXIS "Accel. X-Axis" #define D_AY_AXIS "Accel. Y-Axis" @@ -666,6 +674,7 @@ #define D_SENSOR_HRXL_RX "HRXL Rx" #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" +#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" @@ -785,4 +794,8 @@ #define D_AS3935_CAL_FAIL "calibration failed" #define D_AS3935_CAL_OK "calibration set to:" +//xsns_68_opentherm.ino +#define D_SENSOR_BOILER_OT_RX "OpenTherm RX" +#define D_SENSOR_BOILER_OT_TX "OpenTherm TX" + #endif // _LANGUAGE_ZH_TW_H_ diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 99b33bd5d..72a763b3c 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -478,6 +478,10 @@ // #define USE_SI1145 // [I2cDriver19] Enable SI1145/46/47 sensor (I2C address 0x60) (+1k code) // #define USE_LM75AD // [I2cDriver20] Enable LM75AD sensor (I2C addresses 0x48 - 0x4F) (+0k5 code) // #define USE_APDS9960 // [I2cDriver21] Enable APDS9960 Proximity Sensor (I2C address 0x39). Disables SHT and VEML6070 (+4k7 code) + #define USE_APDS9960_GESTURE // Enable APDS9960 Gesture feature (+2k code) + #define USE_APDS9960_PROXIMITY // Enable APDS9960 Proximity feature (>50 code) + #define USE_APDS9960_COLOR // Enable APDS9960 Color feature (+0.8k code) + #define USE_APDS9960_STARTMODE 0 // Default to enable Gesture mode // #define USE_MCP230xx // [I2cDriver22] Enable MCP23008/MCP23017 - Must define I2C Address in #define USE_MCP230xx_ADDR below - range 0x20 - 0x27 (+4k7 code) // #define USE_MCP230xx_ADDR 0x20 // Enable MCP23008/MCP23017 I2C Address to use (Must be within range 0x20 through 0x26 - set according to your wired setup) // #define USE_MCP230xx_OUTPUT // Enable MCP23008/MCP23017 OUTPUT support through sensor29 commands (+1k5 code) @@ -574,6 +578,10 @@ //#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 + #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) // -- Power monitoring sensors -------------------- #define USE_ENERGY_MARGIN_DETECTION // Add support for Energy Margin detection (+1k6 code) @@ -649,6 +657,8 @@ //#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_WINDMETER // Add support for analog anemometer (+2k2 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) @@ -658,9 +668,34 @@ //#define USE_HRE // Add support for Badger HR-E Water Meter (+1k4 code) //#define USE_A4988_STEPPER // Add support for A4988/DRV8825 stepper-motor-driver-circuit (+10k5 code) -//#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 +// -- Thermostat control ---------------------------- +//#define USE_THERMOSTAT // Add support for Thermostat + #define THERMOSTAT_CONTROLLER_OUTPUTS 1 // Number of outputs to be controlled independently + #define THERMOSTAT_SENSOR_NAME "DS18B20" // Name of the local sensor to be used + #define THERMOSTAT_RELAY_NUMBER 1 // Default output relay number for the first controller (+i for following ones) + #define THERMOSTAT_SWITCH_NUMBER 1 // Default input switch number for the first controller (+i for following ones) + #define THERMOSTAT_TIME_ALLOW_RAMPUP 300 // Default time in seconds after last target update to allow ramp-up controller phase in minutes + #define THERMOSTAT_TIME_RAMPUP_MAX 960 // Default time maximum ramp-up controller duration in minutes + #define THERMOSTAT_TIME_RAMPUP_CYCLE 1800 // Default time ramp-up cycle in seconds + #define THERMOSTAT_TIME_SENS_LOST 30 // Maximum time w/o sensor update to set it as lost in minutes + #define THERMOSTAT_TEMP_SENS_NUMBER 1 // Default temperature sensor number + #define THERMOSTAT_TIME_MANUAL_TO_AUTO 60 // Default time without input switch active to change from manual to automatic in minutes + #define THERMOSTAT_TIME_ON_LIMIT 120 // Default maximum time with output active in minutes + #define THERMOSTAT_TIME_RESET 12000 // Default reset time of the PI controller in seconds + #define THERMOSTAT_TIME_PI_CYCLE 30 // Default cycle time for the thermostat controller in minutes + #define THERMOSTAT_TIME_MAX_ACTION 20 // Default maximum thermostat time per cycle in minutes + #define THERMOSTAT_TIME_MIN_ACTION 4 // Default minimum thermostat time per cycle in minutes + #define THERMOSTAT_TIME_MIN_TURNOFF_ACTION 3 // Default minimum turnoff time in minutes, below it the thermostat will be held on + #define THERMOSTAT_PROP_BAND 4 // Default proportional band of the PI controller in degrees celsius + #define THERMOSTAT_TEMP_RESET_ANTI_WINDUP 8 // Default range where reset antiwindup is disabled, in tenths of degrees celsius + #define THERMOSTAT_TEMP_HYSTERESIS 1 // Default range hysteresis for temperature PI controller, in tenths of degrees celsius + #define THERMOSTAT_TEMP_FROST_PROTECT 40 // Default minimum temperature for frost protection, in tenths of degrees celsius + #define THERMOSTAT_TEMP_RAMPUP_DELTA_IN 4 // Default minimum delta temperature to target to get into rampup mode, in tenths of degrees celsius + #define THERMOSTAT_TEMP_RAMPUP_DELTA_OUT 2 // Default minimum delta temperature to target to get out of the rampup mode, in tenths of degrees celsius + #define THERMOSTAT_TEMP_PI_RAMPUP_ACC_E 200 // Default accumulated error when switching from ramp-up controller to PI in hundreths of degrees celsius + #define THERMOSTAT_TIME_OUTPUT_DELAY 180 // Default output delay between state change and real actuation event (f.i. valve open/closed) + #define THERMOSTAT_TEMP_INIT 180 // Default init target temperature for the thermostat controller + #define THERMOSTAT_TIME_MAX_OUTPUT_INCONSIST 3 // Default maximum time where the input and the outpus shall differ (for diagnostic) in minutes // -- End of general directives ------------------- diff --git a/tasmota/settings.h b/tasmota/settings.h index 81ee3baf8..6b74cb269 100644 --- a/tasmota/settings.h +++ b/tasmota/settings.h @@ -481,6 +481,12 @@ struct { uint8_t shutter_position[MAX_SHUTTERS]; // E80 uint8_t shutter_startrelay[MAX_SHUTTERS]; // E84 uint8_t pcf8574_config[MAX_PCF8574]; // E88 + uint8_t ot_hot_water_setpoint; // E8C + uint8_t ot_boiler_setpoint; // E8D + uint8_t ot_flags; // E8E + + uint8_t free_e8f[1]; // E8F + uint16_t dimmer_hw_min; // E90 uint16_t dimmer_hw_max; // E92 uint32_t deepsleep; // E94 @@ -527,8 +533,13 @@ struct { uint8_t zb_free_byte; // F33 uint16_t pms_wake_interval; // F34 uint8_t config_version; // F36 + uint8_t windmeter_pulses_x_rot; // F37 + uint16_t windmeter_radius; // F38 + uint16_t windmeter_pulse_debounce; // F3A + int16_t windmeter_speed_factor; // F3C + uint8_t windmeter_tele_pchange; // F3E - uint8_t free_f37[129]; // F37 - Decrement if adding new Setting variables just above and below + uint8_t free_f3f[121]; // F3F - 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 911c69c2d..83527ea6f 100644 --- a/tasmota/settings.ino +++ b/tasmota/settings.ino @@ -715,6 +715,12 @@ void SettingsDefaultSet2(void) { memset((char*)&Settings +16, 0x00, sizeof(Settings) -16); + // this little trick allows GCC to optimize the assignment by grouping values and doing only ORs + SysBitfield flag = { 0 }; + SysBitfield2 flag2 = { 0 }; + SysBitfield3 flag3 = { 0 }; + SysBitfield4 flag4 = { 0 }; + #ifdef ESP8266 // Settings.config_version = 0; // ESP8266 (Has been 0 for long time) #endif // ESP8266 @@ -722,13 +728,13 @@ void SettingsDefaultSet2(void) Settings.config_version = 1; // ESP32 #endif // ESP32 - Settings.flag.stop_flash_rotate = APP_FLASH_CYCLE; - Settings.flag.global_state = APP_ENABLE_LEDLINK; - Settings.flag3.sleep_normal = APP_NORMAL_SLEEP; - Settings.flag3.no_power_feedback = APP_NO_RELAY_SCAN; - Settings.flag3.fast_power_cycle_disable = APP_DISABLE_POWERCYCLE; - Settings.flag3.bootcount_update = DEEPSLEEP_BOOTCOUNT; - Settings.flag3.compatibility_check = OTA_COMPATIBILITY; + flag.stop_flash_rotate |= APP_FLASH_CYCLE; + flag.global_state |= APP_ENABLE_LEDLINK; + flag3.sleep_normal |= APP_NORMAL_SLEEP; + flag3.no_power_feedback |= APP_NO_RELAY_SCAN; + flag3.fast_power_cycle_disable |= APP_DISABLE_POWERCYCLE; + flag3.bootcount_update |= DEEPSLEEP_BOOTCOUNT; + flag3.compatibility_check |= OTA_COMPATIBILITY; Settings.save_data = SAVE_DATA; Settings.param[P_BACKLOG_DELAY] = MIN_BACKLOG_DELAY; Settings.param[P_BOOT_LOOP_OFFSET] = BOOT_LOOP_OFFSET; // SetOption36 @@ -739,7 +745,7 @@ void SettingsDefaultSet2(void) } // Module -// Settings.flag.interlock = 0; +// flag.interlock |= 0; Settings.interlock[0] = 0xFF; // Legacy support using all relays in one interlock group Settings.module = MODULE; ModuleDefault(WEMOS); @@ -751,7 +757,7 @@ void SettingsDefaultSet2(void) SettingsUpdateText(SET_OTAURL, PSTR(OTA_URL)); // Power - Settings.flag.save_state = SAVE_STATE; + flag.save_state |= SAVE_STATE; Settings.power = APP_POWER; Settings.poweronstate = APP_POWERON_STATE; Settings.blinktime = APP_BLINKTIME; @@ -769,8 +775,8 @@ void SettingsDefaultSet2(void) Settings.seriallog_level = SERIAL_LOG_LEVEL; // Wifi - Settings.flag3.use_wifi_scan = WIFI_SCAN_AT_RESTART; - Settings.flag3.use_wifi_rescan = WIFI_SCAN_REGULARLY; + flag3.use_wifi_scan |= WIFI_SCAN_AT_RESTART; + flag3.use_wifi_rescan |= WIFI_SCAN_REGULARLY; Settings.wifi_output_power = 170; Settings.param[P_ARP_GRATUITOUS] = WIFI_ARP_INTERVAL; ParseIp(&Settings.ip_address[0], WIFI_IP_ADDRESS); @@ -791,38 +797,38 @@ void SettingsDefaultSet2(void) Settings.syslog_level = SYS_LOG_LEVEL; // Webserver - Settings.flag2.emulation = EMULATION; - Settings.flag3.gui_hostname_ip = GUI_SHOW_HOSTNAME; - Settings.flag3.mdns_enabled = MDNS_ENABLED; + flag2.emulation |= EMULATION; + flag3.gui_hostname_ip |= GUI_SHOW_HOSTNAME; + flag3.mdns_enabled |= MDNS_ENABLED; Settings.webserver = WEB_SERVER; Settings.weblog_level = WEB_LOG_LEVEL; SettingsUpdateText(SET_WEBPWD, PSTR(WEB_PASSWORD)); SettingsUpdateText(SET_CORS, PSTR(CORS_DOMAIN)); // Button - Settings.flag.button_restrict = KEY_DISABLE_MULTIPRESS; - Settings.flag.button_swap = KEY_SWAP_DOUBLE_PRESS; - Settings.flag.button_single = KEY_ONLY_SINGLE_PRESS; + flag.button_restrict |= KEY_DISABLE_MULTIPRESS; + flag.button_swap |= KEY_SWAP_DOUBLE_PRESS; + flag.button_single |= KEY_ONLY_SINGLE_PRESS; Settings.param[P_HOLD_TIME] = KEY_HOLD_TIME; // Default 4 seconds hold time // Switch for (uint32_t i = 0; i < MAX_SWITCHES; i++) { Settings.switchmode[i] = SWITCH_MODE; } // MQTT - Settings.flag.mqtt_enabled = MQTT_USE; - Settings.flag.mqtt_response = MQTT_RESULT_COMMAND; - Settings.flag.mqtt_offline = MQTT_LWT_MESSAGE; - Settings.flag.mqtt_power_retain = MQTT_POWER_RETAIN; - Settings.flag.mqtt_button_retain = MQTT_BUTTON_RETAIN; - Settings.flag.mqtt_switch_retain = MQTT_SWITCH_RETAIN; - Settings.flag.mqtt_sensor_retain = MQTT_SENSOR_RETAIN; -// Settings.flag.mqtt_serial = 0; - Settings.flag.device_index_enable = MQTT_POWER_FORMAT; - Settings.flag3.time_append_timezone = MQTT_APPEND_TIMEZONE; - Settings.flag3.button_switch_force_local = MQTT_BUTTON_SWITCH_FORCE_LOCAL; - Settings.flag3.no_hold_retain = MQTT_NO_HOLD_RETAIN; - Settings.flag3.use_underscore = MQTT_INDEX_SEPARATOR; - Settings.flag3.grouptopic_mode = MQTT_GROUPTOPIC_FORMAT; + flag.mqtt_enabled |= MQTT_USE; + flag.mqtt_response |= MQTT_RESULT_COMMAND; + flag.mqtt_offline |= MQTT_LWT_MESSAGE; + flag.mqtt_power_retain |= MQTT_POWER_RETAIN; + flag.mqtt_button_retain |= MQTT_BUTTON_RETAIN; + flag.mqtt_switch_retain |= MQTT_SWITCH_RETAIN; + flag.mqtt_sensor_retain |= MQTT_SENSOR_RETAIN; +// flag.mqtt_serial |= 0; + flag.device_index_enable |= MQTT_POWER_FORMAT; + flag3.time_append_timezone |= MQTT_APPEND_TIMEZONE; + flag3.button_switch_force_local |= MQTT_BUTTON_SWITCH_FORCE_LOCAL; + flag3.no_hold_retain |= MQTT_NO_HOLD_RETAIN; + flag3.use_underscore |= MQTT_INDEX_SEPARATOR; + flag3.grouptopic_mode |= MQTT_GROUPTOPIC_FORMAT; SettingsUpdateText(SET_MQTT_HOST, MQTT_HOST); Settings.mqtt_port = MQTT_PORT; SettingsUpdateText(SET_MQTT_CLIENT, MQTT_CLIENT_ID); @@ -856,13 +862,13 @@ void SettingsDefaultSet2(void) Settings.mqttlog_level = MQTT_LOG_LEVEL; // Energy - Settings.flag.no_power_on_check = ENERGY_VOLTAGE_ALWAYS; - Settings.flag2.current_resolution = 3; -// Settings.flag2.voltage_resolution = 0; -// Settings.flag2.wattage_resolution = 0; - Settings.flag2.energy_resolution = ENERGY_RESOLUTION; - Settings.flag3.dds2382_model = ENERGY_DDS2382_MODE; - Settings.flag3.hardware_energy_total = ENERGY_HARDWARE_TOTALS; + flag.no_power_on_check |= ENERGY_VOLTAGE_ALWAYS; + flag2.current_resolution |= 3; +// flag2.voltage_resolution |= 0; +// flag2.wattage_resolution |= 0; + flag2.energy_resolution |= ENERGY_RESOLUTION; + flag3.dds2382_model |= ENERGY_DDS2382_MODE; + flag3.hardware_energy_total |= ENERGY_HARDWARE_TOTALS; Settings.param[P_MAX_POWER_RETRY] = MAX_POWER_RETRY; // Settings.energy_power_delta = 0; Settings.energy_power_calibration = HLW_PREF_PULSE; @@ -892,12 +898,12 @@ void SettingsDefaultSet2(void) Settings.param[P_OVER_TEMP] = ENERGY_OVERTEMP; // IRRemote - Settings.flag.ir_receive_decimal = IR_DATA_RADIX; - Settings.flag3.receive_raw = IR_ADD_RAW_DATA; + flag.ir_receive_decimal |= IR_DATA_RADIX; + flag3.receive_raw |= IR_ADD_RAW_DATA; Settings.param[P_IR_UNKNOW_THRESHOLD] = IR_RCV_MIN_UNKNOWN_SIZE; // RF Bridge - Settings.flag.rf_receive_decimal = RF_DATA_RADIX; + flag.rf_receive_decimal |= RF_DATA_RADIX; // for (uint32_t i = 0; i < 17; i++) { Settings.rf_code[i][0] = 0; } memcpy_P(Settings.rf_code[0], kDefaultRfCode, 9); @@ -913,43 +919,43 @@ void SettingsDefaultSet2(void) // } // Sensor - Settings.flag.temperature_conversion = TEMP_CONVERSION; - Settings.flag.pressure_conversion = PRESSURE_CONVERSION; - Settings.flag2.pressure_resolution = PRESSURE_RESOLUTION; - Settings.flag2.humidity_resolution = HUMIDITY_RESOLUTION; - Settings.flag2.temperature_resolution = TEMP_RESOLUTION; - Settings.flag3.ds18x20_internal_pullup = DS18X20_PULL_UP; - Settings.flag3.counter_reset_on_tele = COUNTER_RESET; + flag.temperature_conversion |= TEMP_CONVERSION; + flag.pressure_conversion |= PRESSURE_CONVERSION; + flag2.pressure_resolution |= PRESSURE_RESOLUTION; + flag2.humidity_resolution |= HUMIDITY_RESOLUTION; + flag2.temperature_resolution |= TEMP_RESOLUTION; + flag3.ds18x20_internal_pullup |= DS18X20_PULL_UP; + flag3.counter_reset_on_tele |= COUNTER_RESET; // Settings.altitude = 0; // Rules // Settings.rule_enabled = 0; // Settings.rule_once = 0; // for (uint32_t i = 1; i < MAX_RULE_SETS; i++) { Settings.rules[i][0] = '\0'; } - Settings.flag2.calc_resolution = CALC_RESOLUTION; + flag2.calc_resolution |= CALC_RESOLUTION; // Timer - Settings.flag3.timers_enable = TIMERS_ENABLED; + flag3.timers_enable |= TIMERS_ENABLED; // Home Assistant - Settings.flag.hass_light = HASS_AS_LIGHT; - Settings.flag.hass_discovery = HOME_ASSISTANT_DISCOVERY_ENABLE; - Settings.flag3.hass_tele_on_power = TELE_ON_POWER; + flag.hass_light |= HASS_AS_LIGHT; + flag.hass_discovery |= HOME_ASSISTANT_DISCOVERY_ENABLE; + flag3.hass_tele_on_power |= TELE_ON_POWER; // Knx - Settings.flag.knx_enabled = KNX_ENABLED; - Settings.flag.knx_enable_enhancement = KNX_ENHANCED; + flag.knx_enabled |= KNX_ENABLED; + flag.knx_enable_enhancement |= KNX_ENHANCED; // Light - Settings.flag.pwm_control = LIGHT_MODE; - Settings.flag.ws_clock_reverse = LIGHT_CLOCK_DIRECTION; - Settings.flag.light_signal = LIGHT_PAIRS_CO2; - Settings.flag.not_power_linked = LIGHT_POWER_CONTROL; - Settings.flag.decimal_text = LIGHT_COLOR_RADIX; - Settings.flag3.pwm_multi_channels = LIGHT_CHANNEL_MODE; - Settings.flag3.slider_dimmer_stay_on = LIGHT_SLIDER_POWER; - Settings.flag4.alexa_ct_range = LIGHT_ALEXA_CT_RANGE; - Settings.flag4.pwm_ct_mode = LIGHT_PWM_CT_MODE; + flag.pwm_control |= LIGHT_MODE; + flag.ws_clock_reverse |= LIGHT_CLOCK_DIRECTION; + flag.light_signal |= LIGHT_PAIRS_CO2; + flag.not_power_linked |= LIGHT_POWER_CONTROL; + flag.decimal_text |= LIGHT_COLOR_RADIX; + flag3.pwm_multi_channels |= LIGHT_CHANNEL_MODE; + flag3.slider_dimmer_stay_on |= LIGHT_SLIDER_POWER; + flag4.alexa_ct_range |= LIGHT_ALEXA_CT_RANGE; + flag4.pwm_ct_mode |= LIGHT_PWM_CT_MODE; Settings.pwm_frequency = PWM_FREQ; Settings.pwm_range = PWM_RANGE; @@ -1036,13 +1042,18 @@ void SettingsDefaultSet2(void) SettingsEnableAllI2cDrivers(); // Tuya - Settings.flag3.tuya_apply_o20 = TUYA_SETOPTION_20; - Settings.flag3.tuya_serial_mqtt_publish = MQTT_TUYA_RECEIVED; + flag3.tuya_apply_o20 |= TUYA_SETOPTION_20; + flag3.tuya_serial_mqtt_publish |= MQTT_TUYA_RECEIVED; - Settings.flag3.buzzer_enable = BUZZER_ENABLE; - Settings.flag3.shutter_mode = SHUTTER_SUPPORT; - Settings.flag3.pcf8574_ports_inverted = PCF8574_INVERT_PORTS; - Settings.flag4.zigbee_use_names = ZIGBEE_FRIENDLY_NAMES; + flag3.buzzer_enable |= BUZZER_ENABLE; + flag3.shutter_mode |= SHUTTER_SUPPORT; + flag3.pcf8574_ports_inverted |= PCF8574_INVERT_PORTS; + flag4.zigbee_use_names |= ZIGBEE_FRIENDLY_NAMES; + + Settings.flag = flag; + Settings.flag2 = flag2; + Settings.flag3 = flag3; + Settings.flag4 = flag4; } /********************************************************************************************/ diff --git a/tasmota/support_features.ino b/tasmota/support_features.ino index aa02d676e..33b771545 100644 --- a/tasmota/support_features.ino +++ b/tasmota/support_features.ino @@ -554,10 +554,16 @@ void GetFeatures(void) #ifdef USE_PING feature6 |= 0x00000080; // xdrv_38_ping.ino #endif +#ifdef USE_WINDMETER + feature6 |= 0x00000100; // xsns_68_windmeter.ino +#endif +#ifdef USE_OPENTHERM + feature6 |= 0x00000200; // xsns_69_opentherm.ino +#endif +#ifdef USE_THERMOSTAT + feature6 |= 0x00000400; // xdrv_39_heating.ino +#endif -// feature6 |= 0x00000100; -// feature6 |= 0x00000200; -// feature6 |= 0x00000400; // feature6 |= 0x00000800; // feature6 |= 0x00001000; @@ -583,6 +589,7 @@ void GetFeatures(void) // feature6 |= 0x10000000; // feature6 |= 0x20000000; // feature6 |= 0x40000000; -// feature6 |= 0x80000000; - +#ifdef USE_WEBCAM + feature6 |= 0x80000000; +#endif } diff --git a/tasmota/tasmota.h b/tasmota/tasmota.h index a1a3cb473..77bbb6786 100644 --- a/tasmota/tasmota.h +++ b/tasmota/tasmota.h @@ -68,7 +68,7 @@ const uint8_t MAX_XDRV_DRIVERS = 96; // Max number of allowed driver driv const uint8_t MAX_XSNS_DRIVERS = 96; // Max number of allowed sensor drivers const uint8_t MAX_I2C_DRIVERS = 96; // Max number of allowed i2c drivers const uint8_t MAX_SHUTTERS = 4; // Max number of shutters -const uint8_t MAX_PCF8574 = 8; // Max number of PCF8574 devices +const uint8_t MAX_PCF8574 = 4; // Max number of PCF8574 devices const uint8_t MAX_RULE_SETS = 3; // Max number of rule sets of size 512 characters const uint16_t MAX_RULE_SIZE = 512; // Max number of characters in rules @@ -319,9 +319,9 @@ 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_MAX }; + SRC_THERMOSTAT, 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"; + "Timer|Rule|MaxPower|MaxEnergy|Overtemp|Light|Knx|Display|Wemo|Hue|Retry|Remote|Shutter|Thermostat"; const uint8_t kDefaultRfCode[9] PROGMEM = { 0x21, 0x16, 0x01, 0x0E, 0x03, 0x48, 0x2E, 0x1A, 0x00 }; diff --git a/tasmota/tasmota_configurations.h b/tasmota/tasmota_configurations.h index dfb2434e3..3fc3cc0e0 100644 --- a/tasmota/tasmota_configurations.h +++ b/tasmota/tasmota_configurations.h @@ -183,6 +183,7 @@ #define USE_HRE // Add support for Badger HR-E Water Meter (+1k4 code) //#define USE_A4988_STEPPER // Add support for A4988/DRV8825 stepper-motor-driver-circuit (+10k5 code) //#define USE_ARDUINO_SLAVE // Add support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem) +//#define USE_WINDMETER // Add support for analog anemometer #undef DEBUG_THEO // Disable debug code #undef USE_DEBUG_DRIVER // Disable debug code #endif // FIRMWARE_SENSORS diff --git a/tasmota/tasmota_template.h b/tasmota/tasmota_template.h index 5f9c23b7c..b3d3b48ba 100644 --- a/tasmota/tasmota_template.h +++ b/tasmota/tasmota_template.h @@ -230,6 +230,9 @@ enum UserSelectablePins { GPIO_ELECTRIQ_MOODL_TX, // ElectriQ iQ-wifiMOODL Serial TX GPIO_AS3935, GPIO_PMS5003_TX, // Plantower PMS5003 Serial interface + GPIO_BOILER_OT_RX, // OpenTherm Boiler RX pin + GPIO_BOILER_OT_TX, // OpenTherm Boiler TX pin + GPIO_WINDMETER_SPEED, // WindMeter speed counter pin GPIO_SENSOR_END }; // Programmer selectable GPIO functionality @@ -317,7 +320,9 @@ const char kSensorNames[] PROGMEM = D_SENSOR_CC1101_GDO0 "|" D_SENSOR_CC1101_GDO2 "|" D_SENSOR_HRXL_RX "|" D_SENSOR_ELECTRIQ_MOODL "|" - D_SENSOR_AS3935 "|" D_SENSOR_PMS5003_TX + D_SENSOR_AS3935 "|" D_SENSOR_PMS5003_TX "|" + D_SENSOR_BOILER_OT_RX "|" D_SENSOR_BOILER_OT_TX "|" + D_SENSOR_WINDMETER_SPEED ; const char kSensorNamesFixed[] PROGMEM = @@ -591,6 +596,9 @@ const uint8_t kGpioNiceList[] PROGMEM = { #if defined(USE_TX20_WIND_SENSOR) || defined(USE_TX23_WIND_SENSOR) GPIO_TX2X_TXD_BLACK, // TX20/TX23 Transmission Pin #endif +#ifdef USE_WINDMETER + GPIO_WINDMETER_SPEED, +#endif #ifdef USE_MP3_PLAYER GPIO_MP3_DFR562, // RB-DFR-562, DFPlayer Mini MP3 Player Serial interface #endif @@ -612,16 +620,20 @@ const uint8_t kGpioNiceList[] PROGMEM = { GPIO_RDM6300_RX, #endif #ifdef USE_IBEACON - GPIO_IBEACON_RX, GPIO_IBEACON_TX, + GPIO_IBEACON_RX, #endif #ifdef USE_GPS - GPIO_GPS_RX, // GPS serial interface GPIO_GPS_TX, // GPS serial interface + GPIO_GPS_RX, // GPS serial interface #endif #ifdef USE_HM10 - GPIO_HM10_RX, // GPS serial interface GPIO_HM10_TX, // GPS serial interface + GPIO_HM10_RX, // GPS serial interface +#endif +#ifdef USE_OPENTHERM + GPIO_BOILER_OT_TX, + GPIO_BOILER_OT_RX, #endif #ifdef USE_MGC3130 diff --git a/tasmota/tasmota_template_ESP32.h b/tasmota/tasmota_template_ESP32.h index 4aaa39ae3..5fac8c85d 100644 --- a/tasmota/tasmota_template_ESP32.h +++ b/tasmota/tasmota_template_ESP32.h @@ -125,6 +125,8 @@ enum UserSelectablePins { GPIO_WEBCAM_PSCLK, GPIO_WEBCAM_HSD, GPIO_WEBCAM_PSRCS, + GPIO_BOILER_OT_RX, GPIO_BOILER_OT_TX, // OpenTherm Boiler TX pin + GPIO_WINDMETER_SPEED, // WindMeter speed counter pin GPIO_SENSOR_END }; enum ProgramSelectablePins { @@ -136,22 +138,22 @@ 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_SWITCH "|" D_SENSOR_SWITCH "n|" - D_SENSOR_RELAY "|" D_SENSOR_RELAY "i|" - D_SENSOR_LED "|" D_SENSOR_LED "i|" - D_SENSOR_COUNTER "|" D_SENSOR_COUNTER "n|" - D_SENSOR_PWM "|" D_SENSOR_PWM "i|" - D_SENSOR_BUZZER "|" D_SENSOR_BUZZER "i|" - D_SENSOR_LED_LINK "|" D_SENSOR_LED_LINK "i|" + 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|" + D_SENSOR_COUNTER "|" D_SENSOR_COUNTER "_n|" + D_SENSOR_PWM "|" D_SENSOR_PWM "_i|" + D_SENSOR_BUZZER "|" D_SENSOR_BUZZER "_i|" + D_SENSOR_LED_LINK "|" D_SENSOR_LED_LINK "_i|" D_SENSOR_I2C_SCL "|" D_SENSOR_I2C_SDA "|" D_SENSOR_SPI_MISO "|" D_SENSOR_SPI_MOSI "|" D_SENSOR_SPI_CLK "|" D_SENSOR_SPI_CS "|" D_SENSOR_SPI_DC "|" D_SENSOR_SSPI_MISO "|" D_SENSOR_SSPI_MOSI "|" D_SENSOR_SSPI_SCLK "|" D_SENSOR_SSPI_CS "|" D_SENSOR_SSPI_DC "|" D_SENSOR_BACKLIGHT "|" D_SENSOR_OLED_RESET "|" D_SENSOR_IRSEND "|" D_SENSOR_IRRECV "|" D_SENSOR_RFSEND "|" D_SENSOR_RFRECV "|" - D_SENSOR_DHT11 "|" D_SENSOR_AM2301 "|" D_SENSOR_SI7021 "|" D_SENSOR_DHT11 "o|" - D_SENSOR_DS18X20 "|" D_SENSOR_DS18X20 "o|" + D_SENSOR_DHT11 "|" D_SENSOR_AM2301 "|" D_SENSOR_SI7021 "|" D_SENSOR_DHT11 "_o|" + D_SENSOR_DS18X20 "|" D_SENSOR_DS18X20 "_o|" D_SENSOR_WS2812 "|" D_SENSOR_MHZ_TX "|" D_SENSOR_MHZ_RX "|" D_SENSOR_PZEM0XX_TX "|" D_SENSOR_PZEM004_RX "|" D_SENSOR_PZEM016_RX "|" D_SENSOR_PZEM017_RX "|" @@ -171,7 +173,7 @@ const char kSensorNames[] PROGMEM = D_SENSOR_RF_SENSOR "|" D_SENSOR_AZ_TX "|" D_SENSOR_AZ_RX "|" D_SENSOR_MAX31855_CS "|" D_SENSOR_MAX31855_CLK "|" D_SENSOR_MAX31855_DO "|" - D_SENSOR_NRG_SEL "|" D_SENSOR_NRG_SEL "i|" D_SENSOR_NRG_CF1 "|" D_SENSOR_HLW_CF "|" D_SENSOR_HJL_CF "|" + D_SENSOR_NRG_SEL "|" D_SENSOR_NRG_SEL "_i|" D_SENSOR_NRG_CF1 "|" D_SENSOR_HLW_CF "|" D_SENSOR_HJL_CF "|" D_SENSOR_MCP39F5_TX "|" D_SENSOR_MCP39F5_RX "|" D_SENSOR_MCP39F5_RST "|" D_SENSOR_PN532_TX "|" D_SENSOR_PN532_RX "|" D_SENSOR_SM16716_CLK "|" D_SENSOR_SM16716_DAT "|" D_SENSOR_SM16716_POWER "|" @@ -179,7 +181,7 @@ 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 "_1a|" D_SENSOR_ROTARY "_1b|" D_SENSOR_ROTARY "_2a|" D_SENSOR_ROTARY "_2b|" D_SENSOR_HRE_CLOCK "|" D_SENSOR_HRE_DATA "|" D_SENSOR_ADE7953_IRQ "|" D_SENSOR_SOLAXX1_TX "|" D_SENSOR_SOLAXX1_RX "|" @@ -191,7 +193,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_SLAVE_TX "|" D_SENSOR_SLAVE_RX "|" D_SENSOR_SLAVE_RESET "|" D_SENSOR_SLAVE_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 "|" @@ -202,7 +204,7 @@ const char kSensorNames[] PROGMEM = D_SENSOR_AS3935 "|" D_ANALOG_INPUT "|" D_TEMPERATURE "|" D_LIGHT "|" - D_SENSOR_BUTTON "|" D_SENSOR_BUTTON "i|" + D_SENSOR_BUTTON "|" D_SENSOR_BUTTON "_i|" D_RANGE "|" D_CT_POWER "|" D_GPIO_WEBCAM_PWDN "|" D_GPIO_WEBCAM_RESET "|" D_GPIO_WEBCAM_XCLK "|" @@ -211,7 +213,9 @@ const char kSensorNames[] PROGMEM = D_GPIO_WEBCAM_VSYNC "|" D_GPIO_WEBCAM_HREF "|" D_GPIO_WEBCAM_PCLK "|" D_GPIO_WEBCAM_PSCLK "|" D_GPIO_WEBCAM_HSD "|" - D_GPIO_WEBCAM_PSRCS + D_GPIO_WEBCAM_PSRCS "|" + D_SENSOR_BOILER_OT_RX "|" D_SENSOR_BOILER_OT_TX "|" + D_SENSOR_WINDMETER_SPEED ; const char kSensorNamesFixed[] PROGMEM = @@ -395,8 +399,8 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_SOLAXX1_RX), // Solax Inverter rx pin #endif // USE_SOLAX_X1 #ifdef USE_LE01MR - AGPIO(GPIO_LE01MR_RX), // F7F LE-01MR energy meter rx pin 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 #endif // USE_ENERGY_SENSOR @@ -432,6 +436,9 @@ const uint16_t kGpioNiceList[] PROGMEM = { #if defined(USE_TX20_WIND_SENSOR) || defined(USE_TX23_WIND_SENSOR) AGPIO(GPIO_TX2X_TXD_BLACK), // TX20/TX23 Transmission Pin #endif +#ifdef USE_WINDMETER + GPIO_WINDMETER_SPEED, +#endif #ifdef USE_MP3_PLAYER AGPIO(GPIO_MP3_DFR562), // RB-DFR-562, DFPlayer Mini MP3 Player Serial interface #endif @@ -453,16 +460,20 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_RDM6300_RX), #endif #ifdef USE_IBEACON - AGPIO(GPIO_IBEACON_RX), AGPIO(GPIO_IBEACON_TX), + AGPIO(GPIO_IBEACON_RX), #endif #ifdef USE_GPS - AGPIO(GPIO_GPS_RX), // GPS serial interface AGPIO(GPIO_GPS_TX), // GPS serial interface + AGPIO(GPIO_GPS_RX), // GPS serial interface #endif #ifdef USE_HM10 - AGPIO(GPIO_HM10_RX), // GPS serial interface AGPIO(GPIO_HM10_TX), // GPS serial interface + AGPIO(GPIO_HM10_RX), // GPS serial interface +#endif +#ifdef USE_OPENTHERM + GPIO_BOILER_OT_TX, + GPIO_BOILER_OT_RX, #endif #ifdef USE_MGC3130 @@ -523,29 +534,12 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_WEBCAM_XCLK), AGPIO(GPIO_WEBCAM_SIOD), AGPIO(GPIO_WEBCAM_SIOC), - -// AGPIO(GPIO_WEBCAM_Y9), -// AGPIO(GPIO_WEBCAM_Y8), -// AGPIO(GPIO_WEBCAM_Y7), -// AGPIO(GPIO_WEBCAM_Y6), -// AGPIO(GPIO_WEBCAM_Y5), -// AGPIO(GPIO_WEBCAM_Y4), -// AGPIO(GPIO_WEBCAM_Y3), -// AGPIO(GPIO_WEBCAM_Y2), - AGPIO(GPIO_WEBCAM_DATA) + MAX_WEBCAM_DATA, - AGPIO(GPIO_WEBCAM_VSYNC), AGPIO(GPIO_WEBCAM_HREF), AGPIO(GPIO_WEBCAM_PCLK), AGPIO(GPIO_WEBCAM_PSCLK), - -// AGPIO(GPIO_WEBCAM_HSD1), -// AGPIO(GPIO_WEBCAM_HSD2), -// AGPIO(GPIO_WEBCAM_HSD3), - AGPIO(GPIO_WEBCAM_HSD) + MAX_WEBCAM_HSD, - AGPIO(GPIO_WEBCAM_PSRCS), #endif }; diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index e74096465..e7a94893d 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -230,6 +230,11 @@ const char HTTP_SCRIPT_CONSOL[] PROGMEM = const char HTTP_MODULE_TEMPLATE_REPLACE[] PROGMEM = "}2%d'>%s (%d}3"; // }2 and }3 are used in below os.replace +const char HTTP_MODULE_TEMPLATE_REPLACE_INDEX[] PROGMEM = + "}2%d'>%s (%d)}3"; // }2 and }3 are used in below os.replace +const char HTTP_MODULE_TEMPLATE_REPLACE_NO_INDEX[] PROGMEM = + "}2%d'>%s}3"; // }2 and }3 are used in below os.replace + const char HTTP_SCRIPT_MODULE_TEMPLATE[] PROGMEM = #ifdef ESP8266 "var os;" @@ -257,7 +262,7 @@ const char HTTP_SCRIPT_MODULE_TEMPLATE[] PROGMEM = "t.style.visibility=(b>0)?'':'hidden';" "}" "function sk(s,g){" // s = value, g = id and name - "var o=os.replace(/}2/g,\"