Note: This is a vibe-coded fork of gabrielkim13/json-logic-cpp.
Run JsonLogic rules with ArduinoJson on ESP8266, ESP32, and other Arduino cores that provide the required C++17 standard-library features.
JsonLogic represents logic as JSON data instead of compiled C++ code. Your firmware can load a rule from flash, a web API, MQTT, a configuration portal, or the serial port and evaluate it against current sensor or device data. This allows users and administrators to change behavior without rebuilding and flashing the firmware.
Typical uses include:
- turning relays, lights, fans, pumps, or alarms on when conditions match
- user-configurable sensor thresholds and schedules
- validating configuration or incoming messages
- selecting modes, notifications, or access policies
- sharing the same rule format between a web application and a device
The rule decides whether or what to do. Your firmware remains responsible for mapping a trusted action name to the actual hardware operation.
Search for JsonLogic in Library Manager and install it. ArduinoJson 7.4.2 or newer is declared as a dependency and will be installed automatically.
The public include is:
#include <JsonLogic.h>Arduino's Library Manager submission checks reject the ArduinoJsonLogic
name for a third-party library, so the registry package and header are named
JsonLogic.
This release targets ESP8266 and ESP32. Classic AVR boards such as the Arduino Uno are not supported because their standard library does not provide the STL features used by the rule engine.
Add JsonLogic from the PlatformIO Registry to your project's lib_deps.
ArduinoJson is declared as a dependency and will be installed automatically.
[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
lib_deps =
JsonLogic#include <ArduinoJson.h>
#include <JsonLogic.h>
using json_logic::Json;
using json_logic::JsonLogic;
Json rule;
Json data;
deserializeJson(rule, R"({"<":[{"var":"temperature"},30]})");
deserializeJson(data, R"({"temperature":24.5})");
JsonLogic* engine = JsonLogic::GetInstance();
Json result = engine->Apply(rule, data);
if (engine->HasError())
{
Serial.println(engine->GetLastError().c_str());
}
else if (result.as<bool>())
{
Serial.println("The rule matched");
}Inputs are ArduinoJson JsonVariantConst views. Results are owning
JsonDocument values exposed as json_logic::Json.
A rule can be stored separately from the firmware:
{
"action": "fan_on",
"when": {
"and": [
{ ">": [{ "var": "temperature" }, 28] },
{ ">": [{ "var": "humidity" }, 65] }
]
}
}Evaluate the when value against live data:
{
"temperature": 31.5,
"humidity": 72
}The result is true, so application code can dispatch the trusted fan_on
action. A configuration UI can later replace the rule with different
thresholds or conditions without changing the device firmware.
See:
examples/Basicfor one rule evaluationexamples/DynamicRulesfor replacing a rule over Serial and dispatching an actionexamples/IoTRulesfor evaluating several automation rules
- Data:
var,missing,missing_some - Logic:
if,==,===,!=,!==,!,!!,or,and - Numeric:
>,>=,<,<=,max,min,+,-,*,/,% - Arrays:
map,reduce,filter,all,none,some,merge,in - Strings and diagnostics:
cat,substr,log
Refer to JsonLogic operations for the rule format.
Applications can add domain-specific operators. Custom operations receive ArduinoJson views and return an owning document:
JsonLogic::GetInstance()->AddOperation(
"average",
[](json_logic::JsonArrayView values, json_logic::JsonView) {
Json result;
result.set(
(values[0].as<double>() + values[1].as<double>()) / 2.0);
return result;
});Remove an operation with RmOperation("average").
On Arduino, invalid operations return a null Json result and store a message
in GetLastError(). Check HasError() after each top-level Apply() call.
On desktop builds with C++ exceptions enabled, invalid operations throw
json_logic::JsonLogicException.
JsonLogic is data, not arbitrary native code, but user-provided rules still need application-level limits:
- accept only known action identifiers and dispatch them in firmware
- limit input size and nesting depth before parsing
- authenticate rules received over a network
- avoid exposing custom operations that perform unrestricted side effects
- test memory use with the largest rules and data expected on the device
CMake first looks for an installed ArduinoJson package. If none is found, it
downloads ArduinoJson 7.4.3 with FetchContent; no dependency source is
vendored in this repository.
cmake -S . -B build
cmake --build build
ctest --test-dir build --output-on-failureUse the library from another CMake project:
add_subdirectory(lib/json-logic-cpp)
target_link_libraries(my_app PRIVATE jsonlogic::jsonlogic)MIT