mirror of
https://github.com/arendst/Tasmota.git
synced 2025-04-25 07:17:16 +00:00
Merge branch 'development' of https://github.com/arendst/Sonoff-Tasmota into development
This commit is contained in:
commit
3e65413df0
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "TasmotaSerial",
|
"name": "TasmotaSerial",
|
||||||
"version": "1.2.0",
|
"version": "1.3.0",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"serial", "io", "TasmotaSerial"
|
"serial", "io", "TasmotaSerial"
|
||||||
],
|
],
|
@ -1,5 +1,5 @@
|
|||||||
name=TasmotaSerial
|
name=TasmotaSerial
|
||||||
version=1.2.0
|
version=1.3.0
|
||||||
author=Theo Arends
|
author=Theo Arends
|
||||||
maintainer=Theo Arends <theo@arends.com>
|
maintainer=Theo Arends <theo@arends.com>
|
||||||
sentence=Implementation of software serial for ESP8266.
|
sentence=Implementation of software serial for ESP8266.
|
@ -29,51 +29,51 @@ extern "C" {
|
|||||||
|
|
||||||
// As the Arduino attachInterrupt has no parameter, lists of objects
|
// As the Arduino attachInterrupt has no parameter, lists of objects
|
||||||
// and callbacks corresponding to each possible GPIO pins have to be defined
|
// and callbacks corresponding to each possible GPIO pins have to be defined
|
||||||
TasmotaSerial *ObjList[16];
|
TasmotaSerial *tms_obj_list[16];
|
||||||
|
|
||||||
#ifdef TM_SERIAL_USE_IRAM
|
#ifdef TM_SERIAL_USE_IRAM
|
||||||
void ICACHE_RAM_ATTR sws_isr_0() { ObjList[0]->rxRead(); };
|
void ICACHE_RAM_ATTR tms_isr_0() { tms_obj_list[0]->rxRead(); };
|
||||||
void ICACHE_RAM_ATTR sws_isr_1() { ObjList[1]->rxRead(); };
|
void ICACHE_RAM_ATTR tms_isr_1() { tms_obj_list[1]->rxRead(); };
|
||||||
void ICACHE_RAM_ATTR sws_isr_2() { ObjList[2]->rxRead(); };
|
void ICACHE_RAM_ATTR tms_isr_2() { tms_obj_list[2]->rxRead(); };
|
||||||
void ICACHE_RAM_ATTR sws_isr_3() { ObjList[3]->rxRead(); };
|
void ICACHE_RAM_ATTR tms_isr_3() { tms_obj_list[3]->rxRead(); };
|
||||||
void ICACHE_RAM_ATTR sws_isr_4() { ObjList[4]->rxRead(); };
|
void ICACHE_RAM_ATTR tms_isr_4() { tms_obj_list[4]->rxRead(); };
|
||||||
void ICACHE_RAM_ATTR sws_isr_5() { ObjList[5]->rxRead(); };
|
void ICACHE_RAM_ATTR tms_isr_5() { tms_obj_list[5]->rxRead(); };
|
||||||
// Pin 6 to 11 can not be used
|
// Pin 6 to 11 can not be used
|
||||||
void ICACHE_RAM_ATTR sws_isr_12() { ObjList[12]->rxRead(); };
|
void ICACHE_RAM_ATTR tms_isr_12() { tms_obj_list[12]->rxRead(); };
|
||||||
void ICACHE_RAM_ATTR sws_isr_13() { ObjList[13]->rxRead(); };
|
void ICACHE_RAM_ATTR tms_isr_13() { tms_obj_list[13]->rxRead(); };
|
||||||
void ICACHE_RAM_ATTR sws_isr_14() { ObjList[14]->rxRead(); };
|
void ICACHE_RAM_ATTR tms_isr_14() { tms_obj_list[14]->rxRead(); };
|
||||||
void ICACHE_RAM_ATTR sws_isr_15() { ObjList[15]->rxRead(); };
|
void ICACHE_RAM_ATTR tms_isr_15() { tms_obj_list[15]->rxRead(); };
|
||||||
#else
|
#else
|
||||||
void sws_isr_0() { ObjList[0]->rxRead(); };
|
void tms_isr_0() { tms_obj_list[0]->rxRead(); };
|
||||||
void sws_isr_1() { ObjList[1]->rxRead(); };
|
void tms_isr_1() { tms_obj_list[1]->rxRead(); };
|
||||||
void sws_isr_2() { ObjList[2]->rxRead(); };
|
void tms_isr_2() { tms_obj_list[2]->rxRead(); };
|
||||||
void sws_isr_3() { ObjList[3]->rxRead(); };
|
void tms_isr_3() { tms_obj_list[3]->rxRead(); };
|
||||||
void sws_isr_4() { ObjList[4]->rxRead(); };
|
void tms_isr_4() { tms_obj_list[4]->rxRead(); };
|
||||||
void sws_isr_5() { ObjList[5]->rxRead(); };
|
void tms_isr_5() { tms_obj_list[5]->rxRead(); };
|
||||||
// Pin 6 to 11 can not be used
|
// Pin 6 to 11 can not be used
|
||||||
void sws_isr_12() { ObjList[12]->rxRead(); };
|
void tms_isr_12() { tms_obj_list[12]->rxRead(); };
|
||||||
void sws_isr_13() { ObjList[13]->rxRead(); };
|
void tms_isr_13() { tms_obj_list[13]->rxRead(); };
|
||||||
void sws_isr_14() { ObjList[14]->rxRead(); };
|
void tms_isr_14() { tms_obj_list[14]->rxRead(); };
|
||||||
void sws_isr_15() { ObjList[15]->rxRead(); };
|
void tms_isr_15() { tms_obj_list[15]->rxRead(); };
|
||||||
#endif // TM_SERIAL_USE_IRAM
|
#endif // TM_SERIAL_USE_IRAM
|
||||||
|
|
||||||
static void (*ISRList[16])() = {
|
static void (*ISRList[16])() = {
|
||||||
sws_isr_0,
|
tms_isr_0,
|
||||||
sws_isr_1,
|
tms_isr_1,
|
||||||
sws_isr_2,
|
tms_isr_2,
|
||||||
sws_isr_3,
|
tms_isr_3,
|
||||||
sws_isr_4,
|
tms_isr_4,
|
||||||
sws_isr_5,
|
tms_isr_5,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
sws_isr_12,
|
tms_isr_12,
|
||||||
sws_isr_13,
|
tms_isr_13,
|
||||||
sws_isr_14,
|
tms_isr_14,
|
||||||
sws_isr_15
|
tms_isr_15
|
||||||
};
|
};
|
||||||
|
|
||||||
TasmotaSerial::TasmotaSerial(int receive_pin, int transmit_pin)
|
TasmotaSerial::TasmotaSerial(int receive_pin, int transmit_pin)
|
||||||
@ -91,7 +91,7 @@ TasmotaSerial::TasmotaSerial(int receive_pin, int transmit_pin)
|
|||||||
// Use getCycleCount() loop to get as exact timing as possible
|
// Use getCycleCount() loop to get as exact timing as possible
|
||||||
m_bit_time = ESP.getCpuFreqMHz() *1000000 /TM_SERIAL_BAUDRATE;
|
m_bit_time = ESP.getCpuFreqMHz() *1000000 /TM_SERIAL_BAUDRATE;
|
||||||
pinMode(m_rx_pin, INPUT);
|
pinMode(m_rx_pin, INPUT);
|
||||||
ObjList[m_rx_pin] = this;
|
tms_obj_list[m_rx_pin] = this;
|
||||||
attachInterrupt(m_rx_pin, ISRList[m_rx_pin], FALLING);
|
attachInterrupt(m_rx_pin, ISRList[m_rx_pin], FALLING);
|
||||||
}
|
}
|
||||||
if (m_tx_pin > -1) {
|
if (m_tx_pin > -1) {
|
@ -1,12 +1,16 @@
|
|||||||
/* 5.13.1a
|
/* 5.13.1a
|
||||||
* Change user_config.h otaurl to http://sonoff.maddox.co.uk/tasmota/sonoff.bin (#2588, #2602)
|
* Change user_config.h otaurl to http://sonoff.maddox.co.uk/tasmota/sonoff.bin (#2588, #2602)
|
||||||
|
* Fix configuration restore regression from 5.13.1
|
||||||
* Fix compile error when ADC is enabled and Rules are disabled (#2608)
|
* Fix compile error when ADC is enabled and Rules are disabled (#2608)
|
||||||
* Fix rule power trigger when no backlog command is used (#2613)
|
* Fix rule power trigger when no backlog command is used (#2613)
|
||||||
* Fix several timer data input and output errors (#2597, #2620)
|
* Fix several timer data input and output errors (#2597, #2620)
|
||||||
* Fix KNX config error (#2628)
|
* Fix KNX config error (#2628)
|
||||||
|
* Fix sensor MHZ-19 vanishing data over time (#2659)
|
||||||
* Add Portuguese in Brazil language file
|
* Add Portuguese in Brazil language file
|
||||||
* Add rule state test for On/Off in addition to 0/1 (#2613)
|
* Add rule state test for On/Off in addition to 0/1 (#2613)
|
||||||
|
* Add hardware serial option to MHZ-19 sensor (#2659)
|
||||||
* Updated Italian language file (#2618)
|
* Updated Italian language file (#2618)
|
||||||
|
* Optimize command handling
|
||||||
*
|
*
|
||||||
* 5.13.1 20180501
|
* 5.13.1 20180501
|
||||||
* Fix JSON buffers size too small for execution in some situations (#2580)
|
* Fix JSON buffers size too small for execution in some situations (#2580)
|
||||||
|
@ -90,6 +90,7 @@
|
|||||||
#define D_JSON_PRESSUREATSEALEVEL "SeaPressure"
|
#define D_JSON_PRESSUREATSEALEVEL "SeaPressure"
|
||||||
#define D_JSON_PROGRAMFLASHSIZE "ProgramFlashSize"
|
#define D_JSON_PROGRAMFLASHSIZE "ProgramFlashSize"
|
||||||
#define D_JSON_PROGRAMSIZE "ProgramSize"
|
#define D_JSON_PROGRAMSIZE "ProgramSize"
|
||||||
|
#define D_JSON_RESET "Reset"
|
||||||
#define D_JSON_RESTARTING "Restarting"
|
#define D_JSON_RESTARTING "Restarting"
|
||||||
#define D_JSON_RESTARTREASON "RestartReason"
|
#define D_JSON_RESTARTREASON "RestartReason"
|
||||||
#define D_JSON_RSSI "RSSI"
|
#define D_JSON_RSSI "RSSI"
|
||||||
|
@ -100,6 +100,7 @@ const char kTasmotaCommands[] PROGMEM =
|
|||||||
int baudrate = APP_BAUDRATE; // Serial interface baud rate
|
int baudrate = APP_BAUDRATE; // Serial interface baud rate
|
||||||
SerialConfig serial_config = SERIAL_8N1; // Serial interface configuration 8 data bits, No parity, 1 stop bit
|
SerialConfig serial_config = SERIAL_8N1; // Serial interface configuration 8 data bits, No parity, 1 stop bit
|
||||||
byte serial_in_byte; // Received byte
|
byte serial_in_byte; // Received byte
|
||||||
|
uint8_t serial_local = 0; // Handle serial locally;
|
||||||
unsigned long serial_polling_window = 0; // Serial polling window
|
unsigned long serial_polling_window = 0; // Serial polling window
|
||||||
int serial_in_byte_counter = 0; // Index in receive buffer
|
int serial_in_byte_counter = 0; // Index in receive buffer
|
||||||
byte dual_hex_code = 0; // Sonoff dual input flag
|
byte dual_hex_code = 0; // Sonoff dual input flag
|
||||||
@ -437,7 +438,12 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len)
|
|||||||
// AddLog(LOG_LEVEL_DEBUG);
|
// AddLog(LOG_LEVEL_DEBUG);
|
||||||
|
|
||||||
int command_code = GetCommandCode(command, sizeof(command), type, kTasmotaCommands);
|
int command_code = GetCommandCode(command, sizeof(command), type, kTasmotaCommands);
|
||||||
if (CMND_BACKLOG == command_code) {
|
if (-1 == command_code) {
|
||||||
|
if (!XdrvCommand(grpflg, type, index, dataBuf, data_len, payload, payload16)) {
|
||||||
|
type = NULL; // Unknown command
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (CMND_BACKLOG == command_code) {
|
||||||
if (data_len) {
|
if (data_len) {
|
||||||
uint8_t bl_pointer = (!backlog_pointer) ? MAX_BACKLOG -1 : backlog_pointer;
|
uint8_t bl_pointer = (!backlog_pointer) ? MAX_BACKLOG -1 : backlog_pointer;
|
||||||
bl_pointer--;
|
bl_pointer--;
|
||||||
@ -1065,12 +1071,7 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len)
|
|||||||
I2cScan(mqtt_data, sizeof(mqtt_data));
|
I2cScan(mqtt_data, sizeof(mqtt_data));
|
||||||
}
|
}
|
||||||
#endif // USE_I2C
|
#endif // USE_I2C
|
||||||
else if (XdrvCommand(grpflg, type, index, dataBuf, data_len, payload, payload16)) {
|
else type = NULL; // Unknown command
|
||||||
// Serviced
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
type = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (type == NULL) {
|
if (type == NULL) {
|
||||||
blinks = 201;
|
blinks = 201;
|
||||||
@ -2431,7 +2432,7 @@ void loop()
|
|||||||
|
|
||||||
if (millis() >= state_loop_timer) StateLoop();
|
if (millis() >= state_loop_timer) StateLoop();
|
||||||
|
|
||||||
SerialInput();
|
if (!serial_local) SerialInput();
|
||||||
|
|
||||||
#ifdef USE_ARDUINO_OTA
|
#ifdef USE_ARDUINO_OTA
|
||||||
ArduinoOTA.handle();
|
ArduinoOTA.handle();
|
||||||
|
@ -486,6 +486,14 @@ void SetSerialBaudrate(int baudrate)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetSerialLocal(bool slocal)
|
||||||
|
{
|
||||||
|
serial_local = slocal;
|
||||||
|
if (slocal) {
|
||||||
|
SetSeriallog(LOG_LEVEL_NONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t GetHash(const char *buffer, size_t size)
|
uint32_t GetHash(const char *buffer, size_t size)
|
||||||
{
|
{
|
||||||
uint32_t hash = 0;
|
uint32_t hash = 0;
|
||||||
|
@ -330,6 +330,8 @@ uint8_t upload_file_type;
|
|||||||
uint8_t upload_progress_dot_count;
|
uint8_t upload_progress_dot_count;
|
||||||
uint8_t config_block_count = 0;
|
uint8_t config_block_count = 0;
|
||||||
uint8_t config_xor_on = 0;
|
uint8_t config_xor_on = 0;
|
||||||
|
uint8_t config_xor_on_set = CONFIG_FILE_XOR;
|
||||||
|
uint8_t *settings_new = NULL;
|
||||||
|
|
||||||
// Helper function to avoid code duplication (saves 4k Flash)
|
// Helper function to avoid code duplication (saves 4k Flash)
|
||||||
static void WebGetArg(const char* arg, char* out, size_t max)
|
static void WebGetArg(const char* arg, char* out, size_t max)
|
||||||
@ -977,10 +979,10 @@ void HandleBackupConfiguration()
|
|||||||
WebServer->send(200, FPSTR(HDR_CTYPE_STREAM), "");
|
WebServer->send(200, FPSTR(HDR_CTYPE_STREAM), "");
|
||||||
memcpy(buffer, &Settings, sizeof(buffer));
|
memcpy(buffer, &Settings, sizeof(buffer));
|
||||||
buffer[0] = CONFIG_FILE_SIGN;
|
buffer[0] = CONFIG_FILE_SIGN;
|
||||||
buffer[1] = (!CONFIG_FILE_XOR)?0:1;
|
buffer[1] = (!config_xor_on_set) ? 0 : 1;
|
||||||
if (buffer[1]) {
|
if (buffer[1]) {
|
||||||
for (uint16_t i = 2; i < sizeof(buffer); i++) {
|
for (uint16_t i = 2; i < sizeof(buffer); i++) {
|
||||||
buffer[i] ^= (CONFIG_FILE_XOR +i);
|
buffer[i] ^= (config_xor_on_set +i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
myClient.write((const char*)buffer, sizeof(buffer));
|
myClient.write((const char*)buffer, sizeof(buffer));
|
||||||
@ -1236,6 +1238,14 @@ void HandleUpgradeFirmwareStart()
|
|||||||
ExecuteCommand(svalue);
|
ExecuteCommand(svalue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SettingsNewFree()
|
||||||
|
{
|
||||||
|
if (settings_new != NULL) {
|
||||||
|
free(settings_new);
|
||||||
|
settings_new = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void HandleUploadDone()
|
void HandleUploadDone()
|
||||||
{
|
{
|
||||||
if (HttpUser()) { return; }
|
if (HttpUser()) { return; }
|
||||||
@ -1275,6 +1285,7 @@ void HandleUploadDone()
|
|||||||
page += FPSTR(HTTP_MSG_RSTRT);
|
page += FPSTR(HTTP_MSG_RSTRT);
|
||||||
restart_flag = 2;
|
restart_flag = 2;
|
||||||
}
|
}
|
||||||
|
SettingsNewFree();
|
||||||
page += F("</div><br/>");
|
page += F("</div><br/>");
|
||||||
page += FPSTR(HTTP_BTN_MAIN);
|
page += FPSTR(HTTP_BTN_MAIN);
|
||||||
ShowPage(page);
|
ShowPage(page);
|
||||||
@ -1302,7 +1313,13 @@ void HandleUploadLoop()
|
|||||||
SettingsSave(1); // Free flash for upload
|
SettingsSave(1); // Free flash for upload
|
||||||
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_UPLOAD D_FILE " %s ..."), upload.filename.c_str());
|
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_UPLOAD D_FILE " %s ..."), upload.filename.c_str());
|
||||||
AddLog(LOG_LEVEL_INFO);
|
AddLog(LOG_LEVEL_INFO);
|
||||||
if (!upload_file_type) {
|
if (upload_file_type) {
|
||||||
|
SettingsNewFree();
|
||||||
|
if (!(settings_new = (uint8_t *)malloc(sizeof(Settings)))) {
|
||||||
|
upload_error = 2;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
MqttRetryCounter(60);
|
MqttRetryCounter(60);
|
||||||
#ifdef USE_EMULATION
|
#ifdef USE_EMULATION
|
||||||
UdpDisconnect();
|
UdpDisconnect();
|
||||||
@ -1343,22 +1360,10 @@ void HandleUploadLoop()
|
|||||||
if (upload_file_type) { // config
|
if (upload_file_type) { // config
|
||||||
if (!upload_error) {
|
if (!upload_error) {
|
||||||
if (upload.currentSize > (sizeof(Settings) - (config_block_count * HTTP_UPLOAD_BUFLEN))) {
|
if (upload.currentSize > (sizeof(Settings) - (config_block_count * HTTP_UPLOAD_BUFLEN))) {
|
||||||
if (config_block_count) { SettingsDefault(); }
|
|
||||||
upload_error = 9;
|
upload_error = 9;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (config_xor_on) {
|
memcpy(settings_new + (config_block_count * HTTP_UPLOAD_BUFLEN), upload.buf, upload.currentSize);
|
||||||
for (uint16_t i = 2; i < upload.currentSize; i++) {
|
|
||||||
upload.buf[i] ^= (CONFIG_FILE_XOR +i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (0 == config_block_count) {
|
|
||||||
SettingsDefaultSet2();
|
|
||||||
memcpy((char*)&Settings +16, upload.buf +16, upload.currentSize -16);
|
|
||||||
memcpy((char*)&Settings +8, upload.buf +8, 4); // Restore version and auto upgrade
|
|
||||||
} else {
|
|
||||||
memcpy((char*)&Settings +(config_block_count * HTTP_UPLOAD_BUFLEN), upload.buf, upload.currentSize);
|
|
||||||
}
|
|
||||||
config_block_count++;
|
config_block_count++;
|
||||||
}
|
}
|
||||||
} else { // firmware
|
} else { // firmware
|
||||||
@ -1376,7 +1381,17 @@ void HandleUploadLoop()
|
|||||||
if (_serialoutput && (upload_progress_dot_count % 80)) {
|
if (_serialoutput && (upload_progress_dot_count % 80)) {
|
||||||
Serial.println();
|
Serial.println();
|
||||||
}
|
}
|
||||||
if (!upload_file_type) {
|
if (upload_file_type) {
|
||||||
|
if (config_xor_on) {
|
||||||
|
for (uint16_t i = 2; i < sizeof(Settings); i++) {
|
||||||
|
settings_new[i] ^= (config_xor_on_set +i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SettingsDefaultSet2();
|
||||||
|
memcpy((char*)&Settings +16, settings_new +16, sizeof(Settings) -16);
|
||||||
|
memcpy((char*)&Settings +8, settings_new +8, 4); // Restore version and auto upgrade
|
||||||
|
SettingsNewFree();
|
||||||
|
} else {
|
||||||
if (!Update.end(true)) { // true to set the size to the current progress
|
if (!Update.end(true)) { // true to set the size to the current progress
|
||||||
if (_serialoutput) { Update.printError(Serial); }
|
if (_serialoutput) { Update.printError(Serial); }
|
||||||
upload_error = 6;
|
upload_error = 6;
|
||||||
|
@ -541,7 +541,10 @@ bool MqttCommand()
|
|||||||
char *dataBuf = XdrvMailbox.data;
|
char *dataBuf = XdrvMailbox.data;
|
||||||
|
|
||||||
int command_code = GetCommandCode(command, sizeof(command), type, kMqttCommands);
|
int command_code = GetCommandCode(command, sizeof(command), type, kMqttCommands);
|
||||||
if (CMND_MQTTHOST == command_code) {
|
if (-1 == command_code) {
|
||||||
|
serviced = false; // Unknown command
|
||||||
|
}
|
||||||
|
else if (CMND_MQTTHOST == command_code) {
|
||||||
if ((data_len > 0) && (data_len < sizeof(Settings.mqtt_host))) {
|
if ((data_len > 0) && (data_len < sizeof(Settings.mqtt_host))) {
|
||||||
strlcpy(Settings.mqtt_host, (!strcmp(dataBuf,"0")) ? "" : (1 == payload) ? MQTT_HOST : dataBuf, sizeof(Settings.mqtt_host));
|
strlcpy(Settings.mqtt_host, (!strcmp(dataBuf,"0")) ? "" : (1 == payload) ? MQTT_HOST : dataBuf, sizeof(Settings.mqtt_host));
|
||||||
restart_flag = 2;
|
restart_flag = 2;
|
||||||
@ -740,7 +743,8 @@ bool MqttCommand()
|
|||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, GetStateText(Settings.flag.mqtt_sensor_retain));
|
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, GetStateText(Settings.flag.mqtt_sensor_retain));
|
||||||
}
|
}
|
||||||
else serviced = false;
|
else serviced = false; // Unknown command
|
||||||
|
|
||||||
return serviced;
|
return serviced;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1034,7 +1034,10 @@ boolean LightCommand()
|
|||||||
char option = (1 == XdrvMailbox.data_len) ? XdrvMailbox.data[0] : '\0';
|
char option = (1 == XdrvMailbox.data_len) ? XdrvMailbox.data[0] : '\0';
|
||||||
|
|
||||||
int command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic, kLightCommands);
|
int command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic, kLightCommands);
|
||||||
if ((CMND_COLOR == command_code) && (light_subtype > LST_SINGLE) && (XdrvMailbox.index > 0) && (XdrvMailbox.index <= 6)) {
|
if (-1 == command_code) {
|
||||||
|
serviced = false; // Unknown command
|
||||||
|
}
|
||||||
|
else if ((CMND_COLOR == command_code) && (light_subtype > LST_SINGLE) && (XdrvMailbox.index > 0) && (XdrvMailbox.index <= 6)) {
|
||||||
if (XdrvMailbox.data_len > 0) {
|
if (XdrvMailbox.data_len > 0) {
|
||||||
valid_entry = LightColorEntry(XdrvMailbox.data, XdrvMailbox.data_len);
|
valid_entry = LightColorEntry(XdrvMailbox.data, XdrvMailbox.data_len);
|
||||||
if (valid_entry) {
|
if (valid_entry) {
|
||||||
@ -1272,9 +1275,11 @@ boolean LightCommand()
|
|||||||
else {
|
else {
|
||||||
serviced = false; // Unknown command
|
serviced = false; // Unknown command
|
||||||
}
|
}
|
||||||
|
|
||||||
if (coldim) {
|
if (coldim) {
|
||||||
LightPreparePower();
|
LightPreparePower();
|
||||||
}
|
}
|
||||||
|
|
||||||
return serviced;
|
return serviced;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -384,6 +384,7 @@ boolean IrSendCommand()
|
|||||||
}
|
}
|
||||||
#endif // USE_IR_HVAC
|
#endif // USE_IR_HVAC
|
||||||
else serviced = false; // Unknown command
|
else serviced = false; // Unknown command
|
||||||
|
|
||||||
return serviced;
|
return serviced;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -803,7 +803,10 @@ boolean EnergyCommand()
|
|||||||
unsigned long nvalue = 0;
|
unsigned long nvalue = 0;
|
||||||
|
|
||||||
int command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic, kEnergyCommands);
|
int command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic, kEnergyCommands);
|
||||||
if (CMND_POWERDELTA == command_code) {
|
if (-1 == command_code) {
|
||||||
|
serviced = false; // Unknown command
|
||||||
|
}
|
||||||
|
else if (CMND_POWERDELTA == command_code) {
|
||||||
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 101)) {
|
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 101)) {
|
||||||
Settings.energy_power_delta = (1 == XdrvMailbox.payload) ? DEFAULT_POWER_DELTA : XdrvMailbox.payload;
|
Settings.energy_power_delta = (1 == XdrvMailbox.payload) ? DEFAULT_POWER_DELTA : XdrvMailbox.payload;
|
||||||
}
|
}
|
||||||
@ -1005,16 +1008,16 @@ boolean EnergyCommand()
|
|||||||
unit = UNIT_HOUR;
|
unit = UNIT_HOUR;
|
||||||
}
|
}
|
||||||
#endif // FEATURE_POWER_LIMIT
|
#endif // FEATURE_POWER_LIMIT
|
||||||
else {
|
else serviced = false; // Unknown command
|
||||||
serviced = false;
|
|
||||||
}
|
if (serviced && !status_flag) {
|
||||||
if (!status_flag) {
|
|
||||||
if (Settings.flag.value_units) {
|
if (Settings.flag.value_units) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_LVALUE_SPACE_UNIT, command, nvalue, GetTextIndexed(sunit, sizeof(sunit), unit, kUnitNames));
|
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_LVALUE_SPACE_UNIT, command, nvalue, GetTextIndexed(sunit, sizeof(sunit), unit, kUnitNames));
|
||||||
} else {
|
} else {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_LVALUE, command, nvalue);
|
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_LVALUE, command, nvalue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return serviced;
|
return serviced;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,7 +198,10 @@ boolean SonoffBridgeCommand()
|
|||||||
boolean serviced = true;
|
boolean serviced = true;
|
||||||
|
|
||||||
int command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic, kSonoffBridgeCommands);
|
int command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic, kSonoffBridgeCommands);
|
||||||
if ((command_code >= CMND_RFSYNC) && (command_code <= CMND_RFCODE)) { // RfSync, RfLow, RfHigh, RfHost and RfCode
|
if (-1 == command_code) {
|
||||||
|
serviced = false; // Unknown command
|
||||||
|
}
|
||||||
|
else if ((command_code >= CMND_RFSYNC) && (command_code <= CMND_RFCODE)) { // RfSync, RfLow, RfHigh, RfHost and RfCode
|
||||||
char *p;
|
char *p;
|
||||||
char stemp [10];
|
char stemp [10];
|
||||||
uint32_t code = 0;
|
uint32_t code = 0;
|
||||||
@ -290,7 +293,8 @@ boolean SonoffBridgeCommand()
|
|||||||
} else {
|
} else {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, command, sonoff_bridge_learn_key, D_JSON_LEARNING_ACTIVE);
|
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, command, sonoff_bridge_learn_key, D_JSON_LEARNING_ACTIVE);
|
||||||
}
|
}
|
||||||
} else serviced = false;
|
} else serviced = false; // Unknown command
|
||||||
|
|
||||||
return serviced;
|
return serviced;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,7 +228,10 @@ boolean DomoticzCommand()
|
|||||||
|
|
||||||
if (!strncasecmp_P(XdrvMailbox.topic, PSTR(D_CMND_DOMOTICZ), dmtcz_len)) { // Prefix
|
if (!strncasecmp_P(XdrvMailbox.topic, PSTR(D_CMND_DOMOTICZ), dmtcz_len)) { // Prefix
|
||||||
int command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic +dmtcz_len, kDomoticzCommands);
|
int command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic +dmtcz_len, kDomoticzCommands);
|
||||||
if ((CMND_IDX == command_code) && (XdrvMailbox.index > 0) && (XdrvMailbox.index <= MAX_DOMOTICZ_IDX)) {
|
if (-1 == command_code) {
|
||||||
|
serviced = false; // Unknown command
|
||||||
|
}
|
||||||
|
else if ((CMND_IDX == command_code) && (XdrvMailbox.index > 0) && (XdrvMailbox.index <= MAX_DOMOTICZ_IDX)) {
|
||||||
if (XdrvMailbox.payload >= 0) {
|
if (XdrvMailbox.payload >= 0) {
|
||||||
Settings.domoticz_relay_idx[XdrvMailbox.index -1] = XdrvMailbox.payload;
|
Settings.domoticz_relay_idx[XdrvMailbox.index -1] = XdrvMailbox.payload;
|
||||||
restart_flag = 2;
|
restart_flag = 2;
|
||||||
@ -259,9 +262,10 @@ boolean DomoticzCommand()
|
|||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_DOMOTICZ "%s\":%d}"), command, Settings.domoticz_update_timer);
|
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_DOMOTICZ "%s\":%d}"), command, Settings.domoticz_update_timer);
|
||||||
}
|
}
|
||||||
else serviced = false;
|
else serviced = false; // Unknown command
|
||||||
}
|
}
|
||||||
else serviced = false;
|
else serviced = false; // Unknown command
|
||||||
|
|
||||||
return serviced;
|
return serviced;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,7 +89,10 @@ boolean SerialBridgeCommand()
|
|||||||
boolean serviced = true;
|
boolean serviced = true;
|
||||||
|
|
||||||
int command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic, kSerialBridgeCommands);
|
int command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic, kSerialBridgeCommands);
|
||||||
if ((CMND_SSERIALSEND == command_code) && (XdrvMailbox.index > 0) && (XdrvMailbox.index <= 3)) {
|
if (-1 == command_code) {
|
||||||
|
serviced = false; // Unknown command
|
||||||
|
}
|
||||||
|
else if ((CMND_SSERIALSEND == command_code) && (XdrvMailbox.index > 0) && (XdrvMailbox.index <= 3)) {
|
||||||
if (XdrvMailbox.data_len > 0) {
|
if (XdrvMailbox.data_len > 0) {
|
||||||
if (1 == XdrvMailbox.index) {
|
if (1 == XdrvMailbox.index) {
|
||||||
SerialBridgeSerial->write(XdrvMailbox.data, XdrvMailbox.data_len);
|
SerialBridgeSerial->write(XdrvMailbox.data, XdrvMailbox.data_len);
|
||||||
@ -114,9 +117,8 @@ boolean SerialBridgeCommand()
|
|||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_LVALUE, command, Settings.sbaudrate * 1200);
|
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_LVALUE, command, Settings.sbaudrate * 1200);
|
||||||
}
|
}
|
||||||
else {
|
else serviced = false; // Unknown command
|
||||||
serviced = false; // Unknown command
|
|
||||||
}
|
|
||||||
return serviced;
|
return serviced;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -345,7 +345,10 @@ boolean TimerCommand()
|
|||||||
|
|
||||||
UpperCase(dataBufUc, XdrvMailbox.data);
|
UpperCase(dataBufUc, XdrvMailbox.data);
|
||||||
int command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic, kTimerCommands);
|
int command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic, kTimerCommands);
|
||||||
if ((CMND_TIMER == command_code) && (index > 0) && (index <= MAX_TIMERS)) {
|
if (-1 == command_code) {
|
||||||
|
serviced = false; // Unknown command
|
||||||
|
}
|
||||||
|
else if ((CMND_TIMER == command_code) && (index > 0) && (index <= MAX_TIMERS)) {
|
||||||
uint8_t error = 0;
|
uint8_t error = 0;
|
||||||
if (XdrvMailbox.data_len) {
|
if (XdrvMailbox.data_len) {
|
||||||
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= MAX_TIMERS)) {
|
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= MAX_TIMERS)) {
|
||||||
@ -484,7 +487,7 @@ boolean TimerCommand()
|
|||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, lbuff);
|
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, lbuff);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else serviced = false;
|
else serviced = false; // Unknown command
|
||||||
|
|
||||||
return serviced;
|
return serviced;
|
||||||
}
|
}
|
||||||
|
@ -391,7 +391,10 @@ boolean RulesCommand()
|
|||||||
uint8_t index = XdrvMailbox.index;
|
uint8_t index = XdrvMailbox.index;
|
||||||
|
|
||||||
int command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic, kRulesCommands);
|
int command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic, kRulesCommands);
|
||||||
if (CMND_RULE == command_code) {
|
if (-1 == command_code) {
|
||||||
|
serviced = false; // Unknown command
|
||||||
|
}
|
||||||
|
else if (CMND_RULE == command_code) {
|
||||||
if ((XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.rules))) {
|
if ((XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.rules))) {
|
||||||
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 6)) {
|
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 6)) {
|
||||||
switch (XdrvMailbox.payload) {
|
switch (XdrvMailbox.payload) {
|
||||||
@ -447,7 +450,7 @@ boolean RulesCommand()
|
|||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, D_JSON_DONE);
|
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, D_JSON_DONE);
|
||||||
}
|
}
|
||||||
else serviced = false;
|
else serviced = false; // Unknown command
|
||||||
|
|
||||||
return serviced;
|
return serviced;
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* MH-Z19 - CO2 sensor
|
* MH-Z19 - CO2 sensor
|
||||||
*
|
*
|
||||||
* Adapted from EspEasy plugin P049 by Dmitry (rel22 ___ inbox.ru)
|
* Adapted from EspEasy plugin P049 by Dmitry (rel22 ___ inbox.ru)
|
||||||
**********************************************************************************************
|
**********************************************************************************************
|
||||||
* Filter usage
|
* Filter usage
|
||||||
*
|
*
|
||||||
@ -64,17 +64,20 @@ enum MhzFilterOptions {MHZ19_FILTER_OFF, MHZ19_FILTER_OFF_ALLSAMPLES, MHZ19_FILT
|
|||||||
#define CO2_HIGH 1200 // Above this CO2 value show red light
|
#define CO2_HIGH 1200 // Above this CO2 value show red light
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MHZ19_READ_TIMEOUT 500 // Must be way less than 1000
|
#define MHZ19_READ_TIMEOUT 400 // Must be way less than 1000 but enough to read 9 bytes at 9600 bps
|
||||||
#define MHZ19_RETRY_COUNT 8
|
#define MHZ19_RETRY_COUNT 8
|
||||||
|
|
||||||
TasmotaSerial *MhzSerial;
|
TasmotaSerial *MhzSerial;
|
||||||
|
|
||||||
const char kMhzTypes[] PROGMEM = "MHZ19|MHZ19B";
|
const char kMhzTypes[] PROGMEM = "MHZ19|MHZ19B";
|
||||||
|
|
||||||
const uint8_t mhz_cmnd_read_ppm[9] = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79};
|
enum MhzCommands { MHZ_CMND_READPPM, MHZ_CMND_ABCENABLE, MHZ_CMND_ABCDISABLE, MHZ_CMND_ZEROPOINT, MHZ_CMND_RESET };
|
||||||
const uint8_t mhz_cmnd_abc_enable[9] = {0xFF, 0x01, 0x79, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xE6};
|
const uint8_t kMhzCommands[][2] PROGMEM = {
|
||||||
const uint8_t mhz_cmnd_abc_disable[9] = {0xFF, 0x01, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86};
|
{0x86,0x00}, // mhz_cmnd_read_ppm
|
||||||
const uint8_t mhz_cmnd_zeropoint[9] = {0xff, 0x01, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78};
|
{0x79,0xA0}, // mhz_cmnd_abc_enable
|
||||||
|
{0x79,0x00}, // mhz_cmnd_abc_disable
|
||||||
|
{0x87,0x00}, // mhz_cmnd_zeropoint
|
||||||
|
{0x8D,0x00}}; // mhz_cmnd_reset
|
||||||
|
|
||||||
uint8_t mhz_type = 1;
|
uint8_t mhz_type = 1;
|
||||||
uint16_t mhz_last_ppm = 0;
|
uint16_t mhz_last_ppm = 0;
|
||||||
@ -84,11 +87,80 @@ bool mhz_abc_must_apply = false;
|
|||||||
char mhz_types[7];
|
char mhz_types[7];
|
||||||
|
|
||||||
float mhz_temperature = 0;
|
float mhz_temperature = 0;
|
||||||
uint8_t mhz_timer = 0;
|
|
||||||
uint8_t mhz_retry = MHZ19_RETRY_COUNT;
|
uint8_t mhz_retry = MHZ19_RETRY_COUNT;
|
||||||
|
uint8_t mhz_received = 0;
|
||||||
uint8_t mhz_state = 0;
|
uint8_t mhz_state = 0;
|
||||||
|
|
||||||
|
uint8_t mhz_hard_serial = 0;
|
||||||
|
|
||||||
|
/*********************************************************************************************/
|
||||||
|
|
||||||
|
size_t MhzSerialAvailable()
|
||||||
|
{
|
||||||
|
if (mhz_hard_serial) {
|
||||||
|
return Serial.available();
|
||||||
|
} else {
|
||||||
|
return MhzSerial->available();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MhzSerialFlush()
|
||||||
|
{
|
||||||
|
if (mhz_hard_serial) {
|
||||||
|
Serial.flush();
|
||||||
|
} else {
|
||||||
|
MhzSerial->flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t MhzSerialWrite(byte *array, size_t size)
|
||||||
|
{
|
||||||
|
if (mhz_hard_serial) {
|
||||||
|
return Serial.write(array, size);
|
||||||
|
} else {
|
||||||
|
return MhzSerial->write(array, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int MhzSerialRead()
|
||||||
|
{
|
||||||
|
if (mhz_hard_serial) {
|
||||||
|
return Serial.read();
|
||||||
|
} else {
|
||||||
|
return MhzSerial->read();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************************************/
|
||||||
|
|
||||||
|
byte MhzCalculateChecksum(byte *array)
|
||||||
|
{
|
||||||
|
byte checksum = 0;
|
||||||
|
for (byte i = 1; i < 8; i++) {
|
||||||
|
checksum += array[i];
|
||||||
|
}
|
||||||
|
checksum = 255 - checksum;
|
||||||
|
return (checksum +1);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t MhzSendCmd(byte command_id)
|
||||||
|
{
|
||||||
|
uint8_t mhz_send[9] = { 0 };
|
||||||
|
|
||||||
|
mhz_send[0] = 0xFF; // Start byte, fixed
|
||||||
|
mhz_send[1] = 0x01; // Sensor number, 0x01 by default
|
||||||
|
memcpy_P(&mhz_send[2], kMhzCommands[command_id], sizeof(kMhzCommands[0]));
|
||||||
|
/*
|
||||||
|
mhz_send[4] = 0x00;
|
||||||
|
mhz_send[5] = 0x00;
|
||||||
|
mhz_send[6] = 0x00;
|
||||||
|
mhz_send[7] = 0x00;
|
||||||
|
*/
|
||||||
|
mhz_send[8] = MhzCalculateChecksum(mhz_send);
|
||||||
|
|
||||||
|
return MhzSerialWrite(mhz_send, sizeof(mhz_send));
|
||||||
|
}
|
||||||
|
|
||||||
/*********************************************************************************************/
|
/*********************************************************************************************/
|
||||||
|
|
||||||
bool MhzCheckAndApplyFilter(uint16_t ppm, uint8_t s)
|
bool MhzCheckAndApplyFilter(uint16_t ppm, uint8_t s)
|
||||||
@ -126,89 +198,84 @@ bool MhzCheckAndApplyFilter(uint16_t ppm, uint8_t s)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mhz50ms()
|
void MhzEverySecond()
|
||||||
{
|
{
|
||||||
mhz_state++;
|
mhz_state++;
|
||||||
if (4 == mhz_state) { // Every 200 mSec
|
if (8 == mhz_state) { // Every 8 sec start a MH-Z19 measuring cycle (which takes 1005 +5% ms)
|
||||||
mhz_state = 0;
|
mhz_state = 0;
|
||||||
|
|
||||||
uint8_t mhz_response[9];
|
if (mhz_retry) {
|
||||||
|
mhz_retry--;
|
||||||
mhz_timer++;
|
if (!mhz_retry) {
|
||||||
if (6 == mhz_timer) { // MH-Z19 measuring cycle takes 1005 +5% ms
|
mhz_last_ppm = 0;
|
||||||
mhz_timer = 0;
|
mhz_temperature = 0;
|
||||||
|
}
|
||||||
MhzSerial->flush();
|
|
||||||
MhzSerial->write(mhz_cmnd_read_ppm, 9);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (1 == mhz_timer) {
|
MhzSerialFlush(); // Sync reception
|
||||||
if (mhz_retry) {
|
MhzSendCmd(MHZ_CMND_READPPM);
|
||||||
mhz_retry--;
|
mhz_received = 0;
|
||||||
if (!mhz_retry) {
|
}
|
||||||
mhz_last_ppm = 0;
|
|
||||||
mhz_temperature = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long start = millis();
|
if ((mhz_state > 2) && !mhz_received) { // Start reading response after 3 seconds every second until received
|
||||||
uint8_t counter = 0;
|
uint8_t mhz_response[9];
|
||||||
while (((millis() - start) < MHZ19_READ_TIMEOUT) && (counter < 9)) {
|
|
||||||
if (MhzSerial->available() > 0) {
|
|
||||||
mhz_response[counter++] = MhzSerial->read();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AddLogSerial(LOG_LEVEL_DEBUG_MORE, mhz_response, counter);
|
unsigned long start = millis();
|
||||||
|
uint8_t counter = 0;
|
||||||
if (counter < 9) {
|
while (((millis() - start) < MHZ19_READ_TIMEOUT) && (counter < 9)) {
|
||||||
// AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "MH-Z19 comms timeout"));
|
if (MhzSerialAvailable() > 0) {
|
||||||
return;
|
mhz_response[counter++] = MhzSerialRead();
|
||||||
}
|
|
||||||
|
|
||||||
byte crc = 0;
|
|
||||||
for (uint8_t i = 1; i < 8; i++) {
|
|
||||||
crc += mhz_response[i];
|
|
||||||
}
|
|
||||||
crc = 255 - crc;
|
|
||||||
crc++;
|
|
||||||
if (mhz_response[8] != crc) {
|
|
||||||
// AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "MH-Z19 crc error"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (0xFF != mhz_response[0] || 0x86 != mhz_response[1]) {
|
|
||||||
// AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "MH-Z19 bad response"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t u = (mhz_response[6] << 8) | mhz_response[7];
|
|
||||||
if (15000 == u) { // During (and only ever at) sensor boot, 'u' is reported as 15000
|
|
||||||
if (!mhz_abc_enable) {
|
|
||||||
// After bootup of the sensor the ABC will be enabled.
|
|
||||||
// Thus only actively disable after bootup.
|
|
||||||
mhz_abc_must_apply = true;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
uint16_t ppm = (mhz_response[2] << 8) | mhz_response[3];
|
delay(5);
|
||||||
mhz_temperature = ConvertTemp((float)mhz_response[4] - 40);
|
}
|
||||||
uint8_t s = mhz_response[5];
|
}
|
||||||
mhz_type = (s) ? 1 : 2;
|
|
||||||
if (MhzCheckAndApplyFilter(ppm, s)) {
|
|
||||||
mhz_retry = MHZ19_RETRY_COUNT;
|
|
||||||
LightSetSignal(CO2_LOW, CO2_HIGH, mhz_last_ppm);
|
|
||||||
|
|
||||||
if (0 == s || 64 == s) { // Reading is stable.
|
AddLogSerial(LOG_LEVEL_DEBUG_MORE, mhz_response, counter);
|
||||||
if (mhz_abc_must_apply) {
|
|
||||||
mhz_abc_must_apply = false;
|
if (counter < 9) {
|
||||||
if (mhz_abc_enable) {
|
// AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "MH-Z19 comms timeout"));
|
||||||
MhzSerial->write(mhz_cmnd_abc_enable, 9); // Sent sensor ABC Enable
|
return;
|
||||||
} else {
|
}
|
||||||
MhzSerial->write(mhz_cmnd_abc_disable, 9); // Sent sensor ABC Disable
|
|
||||||
}
|
byte crc = MhzCalculateChecksum(mhz_response);
|
||||||
|
if (mhz_response[8] != crc) {
|
||||||
|
// AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "MH-Z19 crc error"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (0xFF != mhz_response[0] || 0x86 != mhz_response[1]) {
|
||||||
|
// AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "MH-Z19 bad response"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mhz_received = 1;
|
||||||
|
|
||||||
|
uint16_t u = (mhz_response[6] << 8) | mhz_response[7];
|
||||||
|
if (15000 == u) { // During (and only ever at) sensor boot, 'u' is reported as 15000
|
||||||
|
if (!mhz_abc_enable) {
|
||||||
|
// After bootup of the sensor the ABC will be enabled.
|
||||||
|
// Thus only actively disable after bootup.
|
||||||
|
mhz_abc_must_apply = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
uint16_t ppm = (mhz_response[2] << 8) | mhz_response[3];
|
||||||
|
mhz_temperature = ConvertTemp((float)mhz_response[4] - 40);
|
||||||
|
uint8_t s = mhz_response[5];
|
||||||
|
mhz_type = (s) ? 1 : 2;
|
||||||
|
if (MhzCheckAndApplyFilter(ppm, s)) {
|
||||||
|
mhz_retry = MHZ19_RETRY_COUNT;
|
||||||
|
LightSetSignal(CO2_LOW, CO2_HIGH, mhz_last_ppm);
|
||||||
|
|
||||||
|
if (0 == s || 64 == s) { // Reading is stable.
|
||||||
|
if (mhz_abc_must_apply) {
|
||||||
|
mhz_abc_must_apply = false;
|
||||||
|
if (mhz_abc_enable) {
|
||||||
|
MhzSendCmd(MHZ_CMND_ABCENABLE);
|
||||||
|
} else {
|
||||||
|
MhzSendCmd(MHZ_CMND_ABCDISABLE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -225,6 +292,8 @@ void Mhz50ms()
|
|||||||
2 - Manual start = ABC Off
|
2 - Manual start = ABC Off
|
||||||
|
|
||||||
3 - Optional filter settings
|
3 - Optional filter settings
|
||||||
|
|
||||||
|
9 - Reset
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool MhzCommandSensor()
|
bool MhzCommandSensor()
|
||||||
@ -233,9 +302,13 @@ bool MhzCommandSensor()
|
|||||||
|
|
||||||
switch (XdrvMailbox.payload) {
|
switch (XdrvMailbox.payload) {
|
||||||
case 2:
|
case 2:
|
||||||
MhzSerial->write(mhz_cmnd_zeropoint, 9);
|
MhzSendCmd(MHZ_CMND_ZEROPOINT);
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_SENSOR_INDEX_SVALUE, XSNS_15, D_JSON_ZERO_POINT_CALIBRATION);
|
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_SENSOR_INDEX_SVALUE, XSNS_15, D_JSON_ZERO_POINT_CALIBRATION);
|
||||||
break;
|
break;
|
||||||
|
case 9:
|
||||||
|
MhzSendCmd(MHZ_CMND_RESET);
|
||||||
|
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_SENSOR_INDEX_SVALUE, XSNS_15, D_JSON_RESET);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
serviced = false;
|
serviced = false;
|
||||||
}
|
}
|
||||||
@ -249,9 +322,19 @@ void MhzInit()
|
|||||||
{
|
{
|
||||||
mhz_type = 0;
|
mhz_type = 0;
|
||||||
if ((pin[GPIO_MHZ_RXD] < 99) && (pin[GPIO_MHZ_TXD] < 99)) {
|
if ((pin[GPIO_MHZ_RXD] < 99) && (pin[GPIO_MHZ_TXD] < 99)) {
|
||||||
MhzSerial = new TasmotaSerial(pin[GPIO_MHZ_RXD], pin[GPIO_MHZ_TXD]);
|
if ((1 == pin[GPIO_MHZ_RXD]) && (3 == pin[GPIO_MHZ_TXD])) {
|
||||||
if (MhzSerial->begin()) {
|
AddLog_P(LOG_LEVEL_DEBUG, PSTR("MHZ: Hardware serial"));
|
||||||
|
baudrate = 9600;
|
||||||
|
SetSerialBaudrate(baudrate);
|
||||||
|
SetSerialLocal(true);
|
||||||
|
mhz_hard_serial = 1;
|
||||||
mhz_type = 1;
|
mhz_type = 1;
|
||||||
|
} else {
|
||||||
|
MhzSerial = new TasmotaSerial(pin[GPIO_MHZ_RXD], pin[GPIO_MHZ_TXD]);
|
||||||
|
if (MhzSerial->begin(9600)) {
|
||||||
|
AddLog_P(LOG_LEVEL_DEBUG, PSTR("MHZ: Software serial"));
|
||||||
|
mhz_type = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -288,8 +371,8 @@ boolean Xsns15(byte function)
|
|||||||
case FUNC_INIT:
|
case FUNC_INIT:
|
||||||
MhzInit();
|
MhzInit();
|
||||||
break;
|
break;
|
||||||
case FUNC_EVERY_50_MSECOND:
|
case FUNC_EVERY_SECOND:
|
||||||
Mhz50ms();
|
MhzEverySecond();
|
||||||
break;
|
break;
|
||||||
case FUNC_COMMAND:
|
case FUNC_COMMAND:
|
||||||
if (XSNS_15 == XdrvMailbox.index) {
|
if (XSNS_15 == XdrvMailbox.index) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user