mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-06 15:59:52 +03:00
add tx_mode back
This commit is contained in:
@@ -128,13 +128,26 @@
|
||||
data-content="Select the main heating circuit to use. Default is HC1."></i></label>
|
||||
<span class="col-xs-9 col-md-5">
|
||||
<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="3">HC3</option>
|
||||
</select>
|
||||
</span>
|
||||
</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>
|
||||
<div class="row form-group">
|
||||
<div class="col-xs-9 col-md-8">
|
||||
|
||||
@@ -23,6 +23,7 @@ function listcustom() {
|
||||
document.getElementById("dallas_gpio").value = custom_config.settings.dallas_gpio;
|
||||
document.getElementById("publish_time").value = custom_config.settings.publish_time;
|
||||
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) {
|
||||
$("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.heating_circuit = parseInt(document.getElementById("heating_circuit").value);
|
||||
custom_config.settings.tx_mode = parseInt(document.getElementById("tx_mode").value);
|
||||
|
||||
custom_uncommited();
|
||||
}
|
||||
|
||||
@@ -8,12 +8,12 @@
|
||||
*/
|
||||
|
||||
// local libraries
|
||||
#include "MyESP.h"
|
||||
#include "ems.h"
|
||||
#include "ems_devices.h"
|
||||
#include "emsuart.h"
|
||||
#include "my_config.h"
|
||||
#include "version.h"
|
||||
#include "MyESP.h"
|
||||
|
||||
// Dallas external temp sensors
|
||||
#include "ds18.h"
|
||||
@@ -88,6 +88,7 @@ typedef struct {
|
||||
uint8_t dallas_gpio; // pin for attaching external dallas temperature sensors
|
||||
bool dallas_parasite; // on/off is using parasite
|
||||
uint8_t heating_circuit; // number of heating circuit, 1 or 2
|
||||
uint8_t tx_mode; // TX mode 1,2 or 3
|
||||
} _EMSESP_Status;
|
||||
|
||||
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, "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, "tx_mode <n>", "changes Tx logic. 1=ems generic, 2=ems+, 3=Junkers HT3"},
|
||||
|
||||
{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"},
|
||||
@@ -1166,6 +1168,9 @@ bool LoadSaveCallback(MYESP_FSACTION action, JsonObject json) {
|
||||
EMSESP_Status.heating_circuit = settings["heating_circuit"] | DEFAULT_HEATINGCIRCUIT;
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -1181,6 +1186,7 @@ bool LoadSaveCallback(MYESP_FSACTION action, JsonObject json) {
|
||||
settings["shower_alert"] = EMSESP_Status.shower_alert;
|
||||
settings["publish_time"] = EMSESP_Status.publish_time;
|
||||
settings["heating_circuit"] = EMSESP_Status.heating_circuit;
|
||||
settings["tx_mode"] = EMSESP_Status.tx_mode;
|
||||
|
||||
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>"));
|
||||
}
|
||||
}
|
||||
|
||||
// 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) {
|
||||
@@ -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_parasite=%s"), EMSESP_Status.dallas_parasite ? "on" : "off");
|
||||
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(" shower_timer=%s"), EMSESP_Status.shower_timer ? "on" : "off");
|
||||
myDebug_P(PSTR(" shower_alert=%s"), EMSESP_Status.shower_alert ? "on" : "off");
|
||||
|
||||
48
src/ems.cpp
48
src/ems.cpp
@@ -7,10 +7,10 @@
|
||||
*/
|
||||
|
||||
#include "ems.h"
|
||||
#include "MyESP.h"
|
||||
#include "ems_devices.h"
|
||||
#include "emsuart.h"
|
||||
#include <CircularBuffer.h> // https://github.com/rlogiacco/CircularBuffer
|
||||
#include "MyESP.h"
|
||||
|
||||
#ifdef TESTS
|
||||
#include "test_data.h"
|
||||
@@ -508,6 +508,11 @@ int _ems_findType(uint16_t type) {
|
||||
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
|
||||
*/
|
||||
@@ -1408,35 +1413,36 @@ void _process_EasyStatusMessage(_EMS_RxTelegram * EMS_RxTelegram) {
|
||||
* EMS+ messages may come in with different offsets so handle them here
|
||||
*/
|
||||
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
|
||||
// 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
|
||||
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.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)
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
|
||||
@@ -170,6 +170,7 @@ typedef struct {
|
||||
uint8_t txRetryCount; // # times the last Tx was re-sent
|
||||
uint8_t emsIDMask; // Buderus: 0x00, Junkers: 0x80
|
||||
uint8_t emsPollAck[1]; // acknowledge buffer for Poll
|
||||
uint8_t emsTxMode; // Tx mode 1, 2 or 3
|
||||
} _EMS_Sys_Status;
|
||||
|
||||
// The Tx send package
|
||||
@@ -425,6 +426,7 @@ void ems_setWarmWaterModeComfort(uint8_t comfort);
|
||||
void ems_setModels();
|
||||
void ems_setTxDisabled(bool b);
|
||||
bool ems_getTxDisabled();
|
||||
void ems_setTxMode(uint8_t mode);
|
||||
|
||||
char * ems_getThermostatDescription(char * buffer, bool name_only = false);
|
||||
char * ems_getBoilerDescription(char * buffer, bool name_only = false);
|
||||
|
||||
@@ -170,6 +170,37 @@ void ICACHE_FLASH_ATTR emsuart_start() {
|
||||
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>
|
||||
*/
|
||||
@@ -182,8 +213,29 @@ _EMS_TX_STATUS ICACHE_FLASH_ATTR emsuart_tx_buffer(uint8_t * buf, uint8_t len) {
|
||||
|
||||
if (len) {
|
||||
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
|
||||
* 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
|
||||
@@ -265,5 +317,6 @@ _EMS_TX_STATUS ICACHE_FLASH_ATTR emsuart_tx_buffer(uint8_t * buf, uint8_t len) {
|
||||
}
|
||||
ETS_UART_INTR_ENABLE(); // receive anything from FIFO...
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -105,7 +105,8 @@ var custom_configfile = {
|
||||
"shower_timer": false,
|
||||
"shower_alert": false,
|
||||
"publish_time": 120,
|
||||
"heating_circuit": 1
|
||||
"heating_circuit": 1,
|
||||
"tx_mode": 1
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user