From 15943ccad65b3343933f4c16bbeca5a318d4a223 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 23 Jan 2022 17:43:17 +0100 Subject: [PATCH] Add command ``Json {}`` Add command ``Json {}`` to enable input of any command as JSON tokens (#14568) --- CHANGELOG.md | 2 ++ RELEASENOTES.md | 2 ++ tasmota/support_command.ino | 38 ++++++++++++++++++++++++++++++++++--- 3 files changed, 39 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 53d642111..3f7e2addc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ All notable changes to this project will be documented in this file. - ESP32 disable serial console when 3 (ESP32) or 2 (Other models) serial interfaces are requested (#14487) - Support for BME688 with latest Bosch-Sensor-API library (#14513) - Command ``SetOption44 1..100`` to set base tolerance percentage for matching incoming IR messages (default 25, max 100) (#14555) +- Command ``Json {}`` to enable input of any command as JSON tokens (#14568) +- Rule variable %color% (#14572) ### Changed - BME68x-Sensor-API library from v3.5.9 to v4.4.7 diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 9d80e0067..61090023a 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -106,6 +106,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo - Command ``WebTime ,`` to show part of date and/or time in web gui based on "2017-03-07T11:08:02-07:00" - Command ``SspmMap 2,1,..`` to map Sonoff SPM scanned module to physical module [#14281](https://github.com/arendst/Tasmota/issues/14281) - Command ``SetOption44 1..100`` to set base tolerance percentage for matching incoming IR messages (default 25, max 100) [#14555](https://github.com/arendst/Tasmota/issues/14555) +- Command ``Json {}`` to enable input of any command as JSON tokens [#14568](https://github.com/arendst/Tasmota/issues/14568) - Commands for ESP32 ethernet configuration ``EthIpAddress``, ``EthGateway``, ``EthSubnetmask``, ``EthDnsServer1`` and ``EthDnsServer2`` [#14385](https://github.com/arendst/Tasmota/issues/14385) - Support for Eastron SDM230 modBus energy meter [#13443](https://github.com/arendst/Tasmota/issues/13443) - PWM Dimmer two button support [#13993](https://github.com/arendst/Tasmota/issues/13993) @@ -118,6 +119,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo - Solax X1 modbus RTS support and offline status [#14305](https://github.com/arendst/Tasmota/issues/14305) - Tasmota favicon to webbrowser tab [#14322](https://github.com/arendst/Tasmota/issues/14322) - Support for BME688 with latest Bosch-Sensor-API library [#14513](https://github.com/arendst/Tasmota/issues/14513) +- Rule variable %color% [#14572](https://github.com/arendst/Tasmota/issues/14572) - ESP32 single binary firmware [#14239](https://github.com/arendst/Tasmota/issues/14239) - ESP32 disable serial console when 3 (ESP32) or 2 (Other models) serial interfaces are requested [#14487](https://github.com/arendst/Tasmota/issues/14487) - ESP32 support for TuyaMcu diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index 392bdddb9..c93cae16b 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -392,11 +392,41 @@ void CmndBacklog(void) { } void CmndJson(void) { - // Json {"POWER":"OFF","Dimmer":100,"Color":"FFD908","HSBColor":"51,97,100","Channel":[100,85,3]} - JsonParser parser((char*)XdrvMailbox.data); + // Json {"template":{"NAME":"Dummy","GPIO":[320,0,321],"FLAG":0,"BASE":18},"power":2,"HSBColor":"51,97,100","Channel":[100,85,3]} + // + // Escape lower level tokens and add quotes around it + // Input: + // {"template":{"NAME":"Dummy","GPIO":[320,0,321],"FLAG":0,"BASE":18},"power":2,"HSBColor":"51,97,100","Channel":[100,85,3]} + // Output (escaped subtokens): + // {"template":"{\"NAME\":\"Dummy\",\"GPIO\":[320,0,321],\"FLAG\":0,\"BASE\":18}","power":2,"HSBColor":"51,97,100","Channel":[100,85,3]} + uint32_t bracket = 0; + String data_buf(""); + data_buf.reserve(XdrvMailbox.data_len); // We need at least the same amount of characters + for (uint32_t index = 0; index < XdrvMailbox.data_len; index++) { + char c = (char)XdrvMailbox.data[index]; + if (c == '{') { + bracket++; + if (2 == bracket) { data_buf += '"'; } // Add start quote + } + if (bracket > 1) { + if (c == '\"') { data_buf += '\\'; } // Escape any quote within second level token + } + data_buf += c; + if (c == '}') { + bracket--; + if (1 == bracket) { data_buf += '"'; } // Add end quote + } + } + + JsonParser parser((char*)data_buf.c_str()); JsonParserObject root = parser.getRootObject(); if (root) { - String backlog; + // Convert to backlog commands + // Input (escaped subtokens): + // {"template":"{\"NAME\":\"Dummy\",\"GPIO\":[320,0,321],\"FLAG\":0,\"BASE\":18}","power":2,"HSBColor":"51,97,100","Channel":[100,85,3]} + // Output: + // template {"NAME":"Dummy","GPIO":[320,0,321],"FLAG":0,"BASE":18};power 2;HSBColor 51,97,100;Channel1 100;Channel2 85;Channel3 3 + String backlog; // We might need a larger string than XdrvMailbox.data_len accomodating decoded arrays for (auto command_key : root) { const char *command = command_key.getStr(); JsonParserToken parameters = command_key.getValue(); @@ -410,6 +440,8 @@ void CmndJson(void) { backlog += " "; backlog += value.getStr(); // Channel1 100;Channel2 85;Channel3 3 } + } else if (parameters.isObject()) { // Should have been escaped +// AddLog(LOG_LEVEL_DEBUG, PSTR("JSN: Object")); } else { if (backlog.length()) { backlog += ";"; } backlog += command;