add tx_mode back

This commit is contained in:
Paul
2019-08-30 23:57:08 +02:00
parent fe4dde94de
commit bbbb9f13ec
7 changed files with 169 additions and 73 deletions

View File

@@ -128,13 +128,26 @@
data-content="Select the main heating circuit to use. Default is HC1."></i></label> data-content="Select the main heating circuit to use. Default is HC1."></i></label>
<span class="col-xs-9 col-md-5"> <span class="col-xs-9 col-md-5">
<select class="form-control input-sm" id="heating_circuit"> <select class="form-control input-sm" id="heating_circuit">
<option selected="selected" value="1">HC1 (default)</option> <option selected="selected" value="1">HC1</option>
<option value="2">HC2</option> <option value="2">HC2</option>
<option value="3">HC3</option> <option value="3">HC3</option>
</select> </select>
</span> </span>
</div> </div>
<div class="row form-group">
<label class="col-xs-3">TX mode<i style="margin-left: 10px;" class="glyphicon glyphicon-info-sign"
aria-hidden="true" data-toggle="popover" data-trigger="hover" data-placement="right"
data-content="Tx mode settings for various EMS brands"></i></label>
<span class="col-xs-9 col-md-5">
<select class="form-control input-sm" id="tx_mode">
<option selected="selected" value="1">1 (EMS generic)</option>
<option value="2">2 (EMS+/EMS2.0)</option>
<option value="3">3 (Junkers HT3)</option>
</select>
</span>
</div>
<br> <br>
<div class="row form-group"> <div class="row form-group">
<div class="col-xs-9 col-md-8"> <div class="col-xs-9 col-md-8">

View File

@@ -23,6 +23,7 @@ function listcustom() {
document.getElementById("dallas_gpio").value = custom_config.settings.dallas_gpio; document.getElementById("dallas_gpio").value = custom_config.settings.dallas_gpio;
document.getElementById("publish_time").value = custom_config.settings.publish_time; document.getElementById("publish_time").value = custom_config.settings.publish_time;
document.getElementById("heating_circuit").value = custom_config.settings.heating_circuit; document.getElementById("heating_circuit").value = custom_config.settings.heating_circuit;
document.getElementById("tx_mode").value = custom_config.settings.tx_mode;
if (custom_config.settings.led) { if (custom_config.settings.led) {
$("input[name=\"led\"][value=\"1\"]").prop("checked", true); $("input[name=\"led\"][value=\"1\"]").prop("checked", true);
@@ -72,6 +73,7 @@ function savecustom() {
custom_config.settings.publish_time = parseInt(document.getElementById("publish_time").value); custom_config.settings.publish_time = parseInt(document.getElementById("publish_time").value);
custom_config.settings.heating_circuit = parseInt(document.getElementById("heating_circuit").value); custom_config.settings.heating_circuit = parseInt(document.getElementById("heating_circuit").value);
custom_config.settings.tx_mode = parseInt(document.getElementById("tx_mode").value);
custom_uncommited(); custom_uncommited();
} }

View File

@@ -8,12 +8,12 @@
*/ */
// local libraries // local libraries
#include "MyESP.h"
#include "ems.h" #include "ems.h"
#include "ems_devices.h" #include "ems_devices.h"
#include "emsuart.h" #include "emsuart.h"
#include "my_config.h" #include "my_config.h"
#include "version.h" #include "version.h"
#include "MyESP.h"
// Dallas external temp sensors // Dallas external temp sensors
#include "ds18.h" #include "ds18.h"
@@ -88,6 +88,7 @@ typedef struct {
uint8_t dallas_gpio; // pin for attaching external dallas temperature sensors uint8_t dallas_gpio; // pin for attaching external dallas temperature sensors
bool dallas_parasite; // on/off is using parasite bool dallas_parasite; // on/off is using parasite
uint8_t heating_circuit; // number of heating circuit, 1 or 2 uint8_t heating_circuit; // number of heating circuit, 1 or 2
uint8_t tx_mode; // TX mode 1,2 or 3
} _EMSESP_Status; } _EMSESP_Status;
typedef struct { typedef struct {
@@ -109,6 +110,7 @@ static const command_t project_cmds[] PROGMEM = {
{true, "shower_alert <on | off>", "stop hot water to send 3 cold burst warnings after max shower time is exceeded"}, {true, "shower_alert <on | off>", "stop hot water to send 3 cold burst warnings after max shower time is exceeded"},
{true, "publish_time <seconds>", "set frequency for publishing data to MQTT (0=off)"}, {true, "publish_time <seconds>", "set frequency for publishing data to MQTT (0=off)"},
{true, "heating_circuit <1 | 2>", "set the main thermostat HC to work with (if using multiple heating circuits)"}, {true, "heating_circuit <1 | 2>", "set the main thermostat HC to work with (if using multiple heating circuits)"},
{true, "tx_mode <n>", "changes Tx logic. 1=ems generic, 2=ems+, 3=Junkers HT3"},
{false, "info", "show current captured on the devices"}, {false, "info", "show current captured on the devices"},
{false, "log <n | b | t | r | v>", "set logging mode to none, basic, thermostat only, raw or verbose"}, {false, "log <n | b | t | r | v>", "set logging mode to none, basic, thermostat only, raw or verbose"},
@@ -1166,6 +1168,9 @@ bool LoadSaveCallback(MYESP_FSACTION action, JsonObject json) {
EMSESP_Status.heating_circuit = settings["heating_circuit"] | DEFAULT_HEATINGCIRCUIT; EMSESP_Status.heating_circuit = settings["heating_circuit"] | DEFAULT_HEATINGCIRCUIT;
ems_setThermostatHC(EMSESP_Status.heating_circuit); ems_setThermostatHC(EMSESP_Status.heating_circuit);
EMSESP_Status.tx_mode = settings["tx_mode"] | 1; // default to 1 (generic)
ems_setTxMode(EMSESP_Status.tx_mode);
return true; return true;
} }
@@ -1181,6 +1186,7 @@ bool LoadSaveCallback(MYESP_FSACTION action, JsonObject json) {
settings["shower_alert"] = EMSESP_Status.shower_alert; settings["shower_alert"] = EMSESP_Status.shower_alert;
settings["publish_time"] = EMSESP_Status.publish_time; settings["publish_time"] = EMSESP_Status.publish_time;
settings["heating_circuit"] = EMSESP_Status.heating_circuit; settings["heating_circuit"] = EMSESP_Status.heating_circuit;
settings["tx_mode"] = EMSESP_Status.tx_mode;
return true; return true;
} }
@@ -1298,6 +1304,18 @@ bool SetListCallback(MYESP_FSACTION action, uint8_t wc, const char * setting, co
myDebug_P(PSTR("Error. Usage: set heating_circuit <1 | 2>")); myDebug_P(PSTR("Error. Usage: set heating_circuit <1 | 2>"));
} }
} }
// tx_mode
if ((strcmp(setting, "tx_mode") == 0) && (wc == 2)) {
uint8_t mode = atoi(value);
if ((mode >= 1) && (mode <= 3)) {
EMSESP_Status.tx_mode = mode;
ems_setTxMode(mode);
ok = true;
} else {
myDebug_P(PSTR("Error. Usage: set tx_mode <1 | 2 | 3>"));
}
}
} }
if (action == MYESP_FSACTION_LIST) { if (action == MYESP_FSACTION_LIST) {
@@ -1306,6 +1324,7 @@ bool SetListCallback(MYESP_FSACTION action, uint8_t wc, const char * setting, co
myDebug_P(PSTR(" dallas_gpio=%d"), EMSESP_Status.dallas_gpio); myDebug_P(PSTR(" dallas_gpio=%d"), EMSESP_Status.dallas_gpio);
myDebug_P(PSTR(" dallas_parasite=%s"), EMSESP_Status.dallas_parasite ? "on" : "off"); myDebug_P(PSTR(" dallas_parasite=%s"), EMSESP_Status.dallas_parasite ? "on" : "off");
myDebug_P(PSTR(" heating_circuit=%d"), EMSESP_Status.heating_circuit); myDebug_P(PSTR(" heating_circuit=%d"), EMSESP_Status.heating_circuit);
myDebug_P(PSTR(" tx_mode=%d"), EMSESP_Status.tx_mode);
myDebug_P(PSTR(" listen_mode=%s"), EMSESP_Status.listen_mode ? "on" : "off"); myDebug_P(PSTR(" listen_mode=%s"), EMSESP_Status.listen_mode ? "on" : "off");
myDebug_P(PSTR(" shower_timer=%s"), EMSESP_Status.shower_timer ? "on" : "off"); myDebug_P(PSTR(" shower_timer=%s"), EMSESP_Status.shower_timer ? "on" : "off");
myDebug_P(PSTR(" shower_alert=%s"), EMSESP_Status.shower_alert ? "on" : "off"); myDebug_P(PSTR(" shower_alert=%s"), EMSESP_Status.shower_alert ? "on" : "off");

View File

@@ -7,10 +7,10 @@
*/ */
#include "ems.h" #include "ems.h"
#include "MyESP.h"
#include "ems_devices.h" #include "ems_devices.h"
#include "emsuart.h" #include "emsuart.h"
#include <CircularBuffer.h> // https://github.com/rlogiacco/CircularBuffer #include <CircularBuffer.h> // https://github.com/rlogiacco/CircularBuffer
#include "MyESP.h"
#ifdef TESTS #ifdef TESTS
#include "test_data.h" #include "test_data.h"
@@ -508,6 +508,11 @@ int _ems_findType(uint16_t type) {
return (typeFound ? i : -1); return (typeFound ? i : -1);
} }
void ems_setTxMode(uint8_t mode) {
EMS_Sys_Status.emsTxMode = mode;
}
/** /**
* debug print a telegram to telnet/serial including the CRC * debug print a telegram to telnet/serial including the CRC
*/ */
@@ -1408,33 +1413,34 @@ void _process_EasyStatusMessage(_EMS_RxTelegram * EMS_RxTelegram) {
* EMS+ messages may come in with different offsets so handle them here * EMS+ messages may come in with different offsets so handle them here
*/ */
void _process_RCPLUSStatusMessage(_EMS_RxTelegram * EMS_RxTelegram) { void _process_RCPLUSStatusMessage(_EMS_RxTelegram * EMS_RxTelegram) {
if (EMS_RxTelegram->offset == 0) { // handle single data values
if (EMS_RxTelegram->data_length == 1) {
switch (EMS_RxTelegram->offset) {
case EMS_OFFSET_RCPLUSStatusMessage_curr: // setpoint target temp
EMS_Thermostat.curr_roomTemp = _toShort(0); // value is * 10
break;
case EMS_OFFSET_RCPLUSStatusMessage_setpoint: // current target temp
EMS_Thermostat.setpoint_roomTemp = _toByte(0); // value is * 2
break;
case EMS_OFFSET_RCPLUSStatusMessage_currsetpoint: // current setpoint temp, e.g. Thermostat -> all, telegram: 10 00 FF 06 01 A5 22
EMS_Thermostat.setpoint_roomTemp = _toByte(0); // value is * 2
break;
case EMS_OFFSET_RCPLUSStatusMessage_mode: // thermostat mode auto/manual
// manual : 10 00 FF 0A 01 A5 02
// auto : Thermostat -> all, type 0x01A5 telegram: 10 00 FF 0A 01 A5 03
EMS_Thermostat.mode = _bitRead(0, 0); // bit 1, mode (auto=1 or manual=0)
EMS_Thermostat.day_mode = _bitRead(0, 1); // get day mode flag
break;
}
} else if (EMS_RxTelegram->data_length > 20) {
// the whole telegram // the whole telegram
// e.g. Thermostat -> all, telegram: 10 00 FF 00 01 A5 00 D7 21 00 00 00 00 30 01 84 01 01 03 01 84 01 F1 00 00 11 01 00 08 63 00 // e.g. Thermostat -> all, telegram: 10 00 FF 00 01 A5 00 D7 21 00 00 00 00 30 01 84 01 01 03 01 84 01 F1 00 00 11 01 00 08 63 00
// 10 00 FF 00 01 A5 80 00 01 30 28 00 30 28 01 54 03 03 01 01 54 02 A8 00 00 11 01 03 FF FF 00 // 10 00 FF 00 01 A5 80 00 01 30 28 00 30 28 01 54 03 03 01 01 54 02 A8 00 00 11 01 03 FF FF 00
EMS_Thermostat.curr_roomTemp = _toShort(EMS_OFFSET_RCPLUSStatusMessage_curr); // value is * 10 EMS_Thermostat.curr_roomTemp = _toShort(EMS_OFFSET_RCPLUSStatusMessage_curr); // value is * 10
EMS_Thermostat.setpoint_roomTemp = _toByte(EMS_OFFSET_RCPLUSStatusMessage_setpoint); // value is * 2 EMS_Thermostat.setpoint_roomTemp = _toByte(EMS_OFFSET_RCPLUSStatusMessage_setpoint); // value is * 2
EMS_Thermostat.day_mode = _bitRead(EMS_OFFSET_RCPLUSStatusMessage_mode, 1); // get day mode flag
EMS_Thermostat.day_mode = _bitRead(EMS_OFFSET_RCPLUSStatusMessage_mode, 1); // get day mode flag EMS_Thermostat.mode = _bitRead(EMS_OFFSET_RCPLUSStatusMessage_mode, 0); // bit 1, mode (auto=1 or manual=0)
EMS_Thermostat.mode = _bitRead(EMS_OFFSET_RCPLUSStatusMessage_mode, 0); // bit 1, mode (auto=1 or manual=0)
}
// current target temp
if (EMS_RxTelegram->offset == EMS_OFFSET_RCPLUSStatusMessage_setpoint) {
EMS_Thermostat.setpoint_roomTemp = _toByte(0); // value is * 2
}
// current setpoint temp, e.g. Thermostat -> all, telegram: 10 00 FF 06 01 A5 22
if (EMS_RxTelegram->offset == 6) {
EMS_Thermostat.setpoint_roomTemp = _toByte(0); // value is * 2
}
// thermostat mode auto/manual, examples:
// manual : 10 00 FF 0A 01 A5 02 (CRC=16) #data=1
// auto : Thermostat -> all, type 0x01A5 telegram: 10 00 FF 0A 01 A5 03 (CRC=17) #data=1
if (EMS_RxTelegram->offset == EMS_OFFSET_RCPLUSStatusMessage_mode) {
EMS_Thermostat.mode = _bitRead(0, 0); // bit 0
} }
EMS_Sys_Status.emsRefreshed = true; // triggers a send the values back via MQTT EMS_Sys_Status.emsRefreshed = true; // triggers a send the values back via MQTT

View File

@@ -170,6 +170,7 @@ typedef struct {
uint8_t txRetryCount; // # times the last Tx was re-sent uint8_t txRetryCount; // # times the last Tx was re-sent
uint8_t emsIDMask; // Buderus: 0x00, Junkers: 0x80 uint8_t emsIDMask; // Buderus: 0x00, Junkers: 0x80
uint8_t emsPollAck[1]; // acknowledge buffer for Poll uint8_t emsPollAck[1]; // acknowledge buffer for Poll
uint8_t emsTxMode; // Tx mode 1, 2 or 3
} _EMS_Sys_Status; } _EMS_Sys_Status;
// The Tx send package // The Tx send package
@@ -425,6 +426,7 @@ void ems_setWarmWaterModeComfort(uint8_t comfort);
void ems_setModels(); void ems_setModels();
void ems_setTxDisabled(bool b); void ems_setTxDisabled(bool b);
bool ems_getTxDisabled(); bool ems_getTxDisabled();
void ems_setTxMode(uint8_t mode);
char * ems_getThermostatDescription(char * buffer, bool name_only = false); char * ems_getThermostatDescription(char * buffer, bool name_only = false);
char * ems_getBoilerDescription(char * buffer, bool name_only = false); char * ems_getBoilerDescription(char * buffer, bool name_only = false);

View File

@@ -170,6 +170,37 @@ void ICACHE_FLASH_ATTR emsuart_start() {
ETS_UART_INTR_ENABLE(); ETS_UART_INTR_ENABLE();
} }
/*
* Send a BRK signal
* Which is a 11-bit set of zero's (11 cycles)
*/
void ICACHE_FLASH_ATTR emsuart_tx_brk() {
uint32_t tmp;
// must make sure Tx FIFO is empty
while (((USS(EMSUART_UART) >> USTXC) & 0xFF) != 0)
;
tmp = ((1 << UCRXRST) | (1 << UCTXRST)); // bit mask
USC0(EMSUART_UART) |= (tmp); // set bits
USC0(EMSUART_UART) &= ~(tmp); // clear bits
// To create a 11-bit <BRK> we set TXD_BRK bit so the break signal will
// automatically be sent when the tx fifo is empty
tmp = (1 << UCBRK);
GPIO_H(TX_MARK_MASK);
USC0(EMSUART_UART) |= (tmp); // set bit
if (EMS_Sys_Status.emsTxMode <= 1) { // classic mode and ems+ (0, 1)
delayMicroseconds(EMSUART_TX_BRK_WAIT);
} else if (EMS_Sys_Status.emsTxMode == 3) { // junkers mode
delayMicroseconds(EMSUART_TX_WAIT_BRK - EMSUART_TX_LAG); // 1144 (11 Bits)
}
USC0(EMSUART_UART) &= ~(tmp); // clear bit
GPIO_L(TX_MARK_MASK);
}
/* /*
* Send to Tx, ending with a <BRK> * Send to Tx, ending with a <BRK>
*/ */
@@ -182,8 +213,29 @@ _EMS_TX_STATUS ICACHE_FLASH_ATTR emsuart_tx_buffer(uint8_t * buf, uint8_t len) {
if (len) { if (len) {
LA_PULSE(50); LA_PULSE(50);
/*
* if (EMS_Sys_Status.emsTxMode == 2) { // With extra tx delay for EMS+
for (uint8_t i = 0; i < len; i++) {
TX_PULSE(EMSUART_BIT_TIME / 4);
USF(EMSUART_UART) = buf[i];
delayMicroseconds(EMSUART_TX_BRK_WAIT); // https://github.com/proddy/EMS-ESP/issues/23#
}
emsuart_tx_brk(); // send <BRK>
} else if (EMS_Sys_Status.emsTxMode == 3) { // Junkers logic by @philrich
for (uint8_t i = 0; i < len; i++) {
TX_PULSE(EMSUART_BIT_TIME / 4);
USF(EMSUART_UART) = buf[i];
// just to be safe wait for tx fifo empty (needed?)
while (((USS(EMSUART_UART) >> USTXC) & 0xff) != 0)
;
// wait until bits are sent on wire
delayMicroseconds(EMSUART_TX_WAIT_BYTE - EMSUART_TX_LAG + EMSUART_TX_WAIT_GAP);
}
emsuart_tx_brk(); // send <BRK>
} else if (EMS_Sys_Status.emsTxMode == 1) {
/*
* based on code from https://github.com/proddy/EMS-ESP/issues/103 by @susisstrolch * based on code from https://github.com/proddy/EMS-ESP/issues/103 by @susisstrolch
* we emit the whole telegram, with Rx interrupt disabled, collecting busmaster response in FIFO. * we emit the whole telegram, with Rx interrupt disabled, collecting busmaster response in FIFO.
* after sending the last char we poll the Rx status until either * after sending the last char we poll the Rx status until either
@@ -209,61 +261,62 @@ _EMS_TX_STATUS ICACHE_FLASH_ATTR emsuart_tx_buffer(uint8_t * buf, uint8_t len) {
#define EMSUART_BUSY_WAIT (EMSUART_BIT_TIME / 8) #define EMSUART_BUSY_WAIT (EMSUART_BIT_TIME / 8)
#define EMS_TX_TO_CHARS (2 + 20) #define EMS_TX_TO_CHARS (2 + 20)
#define EMS_TX_TO_COUNT ((EMS_TX_TO_CHARS)*10 * 8) #define EMS_TX_TO_COUNT ((EMS_TX_TO_CHARS)*10 * 8)
uint16_t wdc = EMS_TX_TO_COUNT; uint16_t wdc = EMS_TX_TO_COUNT;
ETS_UART_INTR_DISABLE(); // disable rx interrupt ETS_UART_INTR_DISABLE(); // disable rx interrupt
// clear Rx status register // clear Rx status register
USC0(EMSUART_UART) |= (1 << UCRXRST); // reset uart rx fifo USC0(EMSUART_UART) |= (1 << UCRXRST); // reset uart rx fifo
emsuart_flush_fifos(); emsuart_flush_fifos();
// throw out the telegram... // throw out the telegram...
for (uint8_t i = 0; i < len && result == EMS_TX_STATUS_OK;) { for (uint8_t i = 0; i < len && result == EMS_TX_STATUS_OK;) {
GPIO_H(TX_MARK_MASK); GPIO_H(TX_MARK_MASK);
wdc = EMS_TX_TO_COUNT; wdc = EMS_TX_TO_COUNT;
volatile uint8_t _usrxc = (USS(EMSUART_UART) >> USRXC) & 0xFF; volatile uint8_t _usrxc = (USS(EMSUART_UART) >> USRXC) & 0xFF;
USF(EMSUART_UART) = buf[i++]; // send each Tx byte USF(EMSUART_UART) = buf[i++]; // send each Tx byte
// wait for echo from busmaster // wait for echo from busmaster
GPIO_L(TX_MARK_MASK); GPIO_L(TX_MARK_MASK);
while (((USS(EMSUART_UART) >> USRXC) & 0xFF) == _usrxc) { while (((USS(EMSUART_UART) >> USRXC) & 0xFF) == _usrxc) {
delayMicroseconds(EMSUART_BUSY_WAIT); // burn CPU cycles... delayMicroseconds(EMSUART_BUSY_WAIT); // burn CPU cycles...
if (--wdc == 0) { if (--wdc == 0) {
EMS_Sys_Status.emsTxStatus = result = EMS_TX_WTD_TIMEOUT; EMS_Sys_Status.emsTxStatus = result = EMS_TX_WTD_TIMEOUT;
break; break;
} }
if (USIR(EMSUART_UART) & (1 << UIBD)) { if (USIR(EMSUART_UART) & (1 << UIBD)) {
USIC(EMSUART_UART) = (1 << UIBD); // clear BRK detect IRQ USIC(EMSUART_UART) = (1 << UIBD); // clear BRK detect IRQ
EMS_Sys_Status.emsTxStatus = result = EMS_TX_BRK_DETECT; EMS_Sys_Status.emsTxStatus = result = EMS_TX_BRK_DETECT;
}
} }
} }
}
// we got the whole telegram in the Rx buffer // we got the whole telegram in the Rx buffer
// on Rx-BRK (bus collision), we simply enable Rx and leave it // on Rx-BRK (bus collision), we simply enable Rx and leave it
// otherwise we send the final Tx-BRK in the loopback and re=enable Rx-INT. // otherwise we send the final Tx-BRK in the loopback and re=enable Rx-INT.
// worst case, we'll see an additional Rx-BRK... // worst case, we'll see an additional Rx-BRK...
if (result != EMS_TX_STATUS_OK) { if (result != EMS_TX_STATUS_OK) {
LA_PULSE(200); // mark Tx error LA_PULSE(200); // mark Tx error
} else { } else {
// neither bus collision nor timeout - send terminating BRK signal // neither bus collision nor timeout - send terminating BRK signal
GPIO_H(TX_MARK_MASK); GPIO_H(TX_MARK_MASK);
if (!(USIS(EMSUART_UART) & (1 << UIBD))) { if (!(USIS(EMSUART_UART) & (1 << UIBD))) {
// no bus collision - send terminating BRK signal // no bus collision - send terminating BRK signal
USC0(EMSUART_UART) |= (1 << UCLBE) | (1 << UCBRK); // enable loopback & set <BRK> USC0(EMSUART_UART) |= (1 << UCLBE) | (1 << UCBRK); // enable loopback & set <BRK>
// wait until BRK detected... // wait until BRK detected...
while (!(USIR(EMSUART_UART) & (1 << UIBD))) { while (!(USIR(EMSUART_UART) & (1 << UIBD))) {
// delayMicroseconds(EMSUART_BUSY_WAIT); // delayMicroseconds(EMSUART_BUSY_WAIT);
delayMicroseconds(EMSUART_BIT_TIME); delayMicroseconds(EMSUART_BIT_TIME);
}
USC0(EMSUART_UART) &= ~((1 << UCBRK) | (1 << UCLBE)); // disable loopback & clear <BRK>
USIC(EMSUART_UART) = (1 << UIBD); // clear BRK detect IRQ
phantomBreak = 1;
} }
GPIO_L(TX_MARK_MASK);
USC0(EMSUART_UART) &= ~((1 << UCBRK) | (1 << UCLBE)); // disable loopback & clear <BRK>
USIC(EMSUART_UART) = (1 << UIBD); // clear BRK detect IRQ
phantomBreak = 1;
} }
GPIO_L(TX_MARK_MASK); ETS_UART_INTR_ENABLE(); // receive anything from FIFO...
} }
ETS_UART_INTR_ENABLE(); // receive anything from FIFO...
} }
return result; return result;
} }

View File

@@ -105,7 +105,8 @@ var custom_configfile = {
"shower_timer": false, "shower_timer": false,
"shower_alert": false, "shower_alert": false,
"publish_time": 120, "publish_time": 120,
"heating_circuit": 1 "heating_circuit": 1,
"tx_mode": 1
} }
}; };