From 016b1dd02964dd9bf1d569dbe13d0e0ec4f856dc Mon Sep 17 00:00:00 2001 From: Theo Arends Date: Wed, 9 May 2018 10:49:43 +0200 Subject: [PATCH 1/2] Optimize command handling Optimize command handling --- sonoff/_releasenotes.ino | 1 + sonoff/sonoff.ino | 14 +++++++------- sonoff/xdrv_00_mqtt.ino | 8 ++++++-- sonoff/xdrv_01_light.ino | 7 ++++++- sonoff/xdrv_02_irremote.ino | 1 + sonoff/xdrv_03_energy.ino | 13 ++++++++----- sonoff/xdrv_04_snfbridge.ino | 8 ++++++-- sonoff/xdrv_05_domoticz.ino | 10 +++++++--- sonoff/xdrv_08_serial_bridge.ino | 10 ++++++---- sonoff/xdrv_09_timers.ino | 7 +++++-- sonoff/xdrv_10_rules.ino | 7 +++++-- 11 files changed, 58 insertions(+), 28 deletions(-) diff --git a/sonoff/_releasenotes.ino b/sonoff/_releasenotes.ino index 2ce37d699..00945950d 100644 --- a/sonoff/_releasenotes.ino +++ b/sonoff/_releasenotes.ino @@ -9,6 +9,7 @@ * Add Portuguese in Brazil language file * Add rule state test for On/Off in addition to 0/1 (#2613) * Updated Italian language file (#2618) + * Optimize command handling * * 5.13.1 20180501 * Fix JSON buffers size too small for execution in some situations (#2580) diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index 5d70e781e..b7b246aa5 100644 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -437,7 +437,12 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len) // AddLog(LOG_LEVEL_DEBUG); 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) { uint8_t bl_pointer = (!backlog_pointer) ? MAX_BACKLOG -1 : backlog_pointer; bl_pointer--; @@ -1065,12 +1070,7 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len) I2cScan(mqtt_data, sizeof(mqtt_data)); } #endif // USE_I2C - else if (XdrvCommand(grpflg, type, index, dataBuf, data_len, payload, payload16)) { - // Serviced - } - else { - type = NULL; - } + else type = NULL; // Unknown command } if (type == NULL) { blinks = 201; diff --git a/sonoff/xdrv_00_mqtt.ino b/sonoff/xdrv_00_mqtt.ino index 8328cef82..d90ae2591 100644 --- a/sonoff/xdrv_00_mqtt.ino +++ b/sonoff/xdrv_00_mqtt.ino @@ -541,7 +541,10 @@ bool MqttCommand() char *dataBuf = XdrvMailbox.data; 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))) { strlcpy(Settings.mqtt_host, (!strcmp(dataBuf,"0")) ? "" : (1 == payload) ? MQTT_HOST : dataBuf, sizeof(Settings.mqtt_host)); 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)); } - else serviced = false; + else serviced = false; // Unknown command + return serviced; } diff --git a/sonoff/xdrv_01_light.ino b/sonoff/xdrv_01_light.ino index 9230c1529..a72ada7f6 100644 --- a/sonoff/xdrv_01_light.ino +++ b/sonoff/xdrv_01_light.ino @@ -1034,7 +1034,10 @@ boolean LightCommand() char option = (1 == XdrvMailbox.data_len) ? XdrvMailbox.data[0] : '\0'; 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) { valid_entry = LightColorEntry(XdrvMailbox.data, XdrvMailbox.data_len); if (valid_entry) { @@ -1272,9 +1275,11 @@ boolean LightCommand() else { serviced = false; // Unknown command } + if (coldim) { LightPreparePower(); } + return serviced; } diff --git a/sonoff/xdrv_02_irremote.ino b/sonoff/xdrv_02_irremote.ino index 896faa37a..99f4dfed7 100644 --- a/sonoff/xdrv_02_irremote.ino +++ b/sonoff/xdrv_02_irremote.ino @@ -384,6 +384,7 @@ boolean IrSendCommand() } #endif // USE_IR_HVAC else serviced = false; // Unknown command + return serviced; } diff --git a/sonoff/xdrv_03_energy.ino b/sonoff/xdrv_03_energy.ino index 264613429..499162223 100644 --- a/sonoff/xdrv_03_energy.ino +++ b/sonoff/xdrv_03_energy.ino @@ -803,7 +803,10 @@ boolean EnergyCommand() unsigned long nvalue = 0; 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)) { Settings.energy_power_delta = (1 == XdrvMailbox.payload) ? DEFAULT_POWER_DELTA : XdrvMailbox.payload; } @@ -1005,16 +1008,16 @@ boolean EnergyCommand() unit = UNIT_HOUR; } #endif // FEATURE_POWER_LIMIT - else { - serviced = false; - } - if (!status_flag) { + else serviced = false; // Unknown command + + if (serviced && !status_flag) { 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)); } else { snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_LVALUE, command, nvalue); } } + return serviced; } diff --git a/sonoff/xdrv_04_snfbridge.ino b/sonoff/xdrv_04_snfbridge.ino index a17558ca1..20c9fa3d1 100644 --- a/sonoff/xdrv_04_snfbridge.ino +++ b/sonoff/xdrv_04_snfbridge.ino @@ -198,7 +198,10 @@ boolean SonoffBridgeCommand() boolean serviced = true; 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 stemp [10]; uint32_t code = 0; @@ -290,7 +293,8 @@ boolean SonoffBridgeCommand() } else { 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; } diff --git a/sonoff/xdrv_05_domoticz.ino b/sonoff/xdrv_05_domoticz.ino index 38a979916..bf9ae023e 100644 --- a/sonoff/xdrv_05_domoticz.ino +++ b/sonoff/xdrv_05_domoticz.ino @@ -228,7 +228,10 @@ boolean DomoticzCommand() if (!strncasecmp_P(XdrvMailbox.topic, PSTR(D_CMND_DOMOTICZ), dmtcz_len)) { // Prefix 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) { Settings.domoticz_relay_idx[XdrvMailbox.index -1] = XdrvMailbox.payload; 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); } - else serviced = false; + else serviced = false; // Unknown command } - else serviced = false; + else serviced = false; // Unknown command + return serviced; } diff --git a/sonoff/xdrv_08_serial_bridge.ino b/sonoff/xdrv_08_serial_bridge.ino index 428dc5e35..455179f98 100644 --- a/sonoff/xdrv_08_serial_bridge.ino +++ b/sonoff/xdrv_08_serial_bridge.ino @@ -89,7 +89,10 @@ boolean SerialBridgeCommand() boolean serviced = true; 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 (1 == XdrvMailbox.index) { 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); } - else { - serviced = false; // Unknown command - } + else serviced = false; // Unknown command + return serviced; } diff --git a/sonoff/xdrv_09_timers.ino b/sonoff/xdrv_09_timers.ino index 533ee818e..889a92937 100644 --- a/sonoff/xdrv_09_timers.ino +++ b/sonoff/xdrv_09_timers.ino @@ -345,7 +345,10 @@ boolean TimerCommand() UpperCase(dataBufUc, XdrvMailbox.data); 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; if (XdrvMailbox.data_len) { 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); } #endif - else serviced = false; + else serviced = false; // Unknown command return serviced; } diff --git a/sonoff/xdrv_10_rules.ino b/sonoff/xdrv_10_rules.ino index 0690c61b5..fa71d0a12 100644 --- a/sonoff/xdrv_10_rules.ino +++ b/sonoff/xdrv_10_rules.ino @@ -391,7 +391,10 @@ boolean RulesCommand() uint8_t index = XdrvMailbox.index; 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.payload >= 0) && (XdrvMailbox.payload <= 6)) { switch (XdrvMailbox.payload) { @@ -447,7 +450,7 @@ boolean RulesCommand() } 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; } From 0aea9ba572f6494e956ef063004aff0bedc59019 Mon Sep 17 00:00:00 2001 From: Theo Arends Date: Wed, 9 May 2018 13:43:22 +0200 Subject: [PATCH 2/2] Add hardware serial option to MHZ-19 Add hardware serial option to MHZ-19 (#2659) --- sonoff/_releasenotes.ino | 1 + sonoff/sonoff.ino | 3 +- sonoff/support.ino | 8 +++++ sonoff/xsns_15_mhz19.ino | 65 +++++++++++++++++++++++++++++++++++----- 4 files changed, 69 insertions(+), 8 deletions(-) diff --git a/sonoff/_releasenotes.ino b/sonoff/_releasenotes.ino index 00945950d..2e6c44bf9 100644 --- a/sonoff/_releasenotes.ino +++ b/sonoff/_releasenotes.ino @@ -8,6 +8,7 @@ * Fix sensor MHZ-19 vanishing data over time (#2659) * Add Portuguese in Brazil language file * 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) * Optimize command handling * diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index b7b246aa5..11c9cb29c 100644 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -100,6 +100,7 @@ const char kTasmotaCommands[] PROGMEM = int baudrate = APP_BAUDRATE; // Serial interface baud rate SerialConfig serial_config = SERIAL_8N1; // Serial interface configuration 8 data bits, No parity, 1 stop bit byte serial_in_byte; // Received byte +uint8_t serial_local = 0; // Handle serial locally; unsigned long serial_polling_window = 0; // Serial polling window int serial_in_byte_counter = 0; // Index in receive buffer byte dual_hex_code = 0; // Sonoff dual input flag @@ -2431,7 +2432,7 @@ void loop() if (millis() >= state_loop_timer) StateLoop(); - SerialInput(); + if (!serial_local) SerialInput(); #ifdef USE_ARDUINO_OTA ArduinoOTA.handle(); diff --git a/sonoff/support.ino b/sonoff/support.ino index 8f18c5a55..1cf6713ab 100644 --- a/sonoff/support.ino +++ b/sonoff/support.ino @@ -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 hash = 0; diff --git a/sonoff/xsns_15_mhz19.ino b/sonoff/xsns_15_mhz19.ino index 52765f4b5..81069954a 100644 --- a/sonoff/xsns_15_mhz19.ino +++ b/sonoff/xsns_15_mhz19.ino @@ -91,6 +91,46 @@ uint8_t mhz_retry = MHZ19_RETRY_COUNT; uint8_t mhz_received = 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) @@ -117,7 +157,8 @@ size_t MhzSendCmd(byte command_id) mhz_send[7] = 0x00; */ mhz_send[8] = MhzCalculateChecksum(mhz_send); - return MhzSerial->write(mhz_send, sizeof(mhz_send)); + + return MhzSerialWrite(mhz_send, sizeof(mhz_send)); } /*********************************************************************************************/ @@ -160,7 +201,7 @@ bool MhzCheckAndApplyFilter(uint16_t ppm, uint8_t s) void MhzEverySecond() { mhz_state++; - if (8 == mhz_state) { // Every 8 sec start a MH-Z19 measuring cycle (which takes 1005 +5% ms) + if (8 == mhz_state) { // Every 8 sec start a MH-Z19 measuring cycle (which takes 1005 +5% ms) mhz_state = 0; if (mhz_retry) { @@ -171,7 +212,7 @@ void MhzEverySecond() } } - MhzSerial->flush(); // Sync reception + MhzSerialFlush(); // Sync reception MhzSendCmd(MHZ_CMND_READPPM); mhz_received = 0; } @@ -182,8 +223,8 @@ void MhzEverySecond() unsigned long start = millis(); uint8_t counter = 0; while (((millis() - start) < MHZ19_READ_TIMEOUT) && (counter < 9)) { - if (MhzSerial->available() > 0) { - mhz_response[counter++] = MhzSerial->read(); + if (MhzSerialAvailable() > 0) { + mhz_response[counter++] = MhzSerialRead(); } else { delay(5); } @@ -281,9 +322,19 @@ void MhzInit() { mhz_type = 0; if ((pin[GPIO_MHZ_RXD] < 99) && (pin[GPIO_MHZ_TXD] < 99)) { - MhzSerial = new TasmotaSerial(pin[GPIO_MHZ_RXD], pin[GPIO_MHZ_TXD]); - if (MhzSerial->begin(9600)) { + if ((1 == pin[GPIO_MHZ_RXD]) && (3 == pin[GPIO_MHZ_TXD])) { + AddLog_P(LOG_LEVEL_DEBUG, PSTR("MHZ: Hardware serial")); + baudrate = 9600; + SetSerialBaudrate(baudrate); + SetSerialLocal(true); + mhz_hard_serial = 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; + } } } }