Exploring an idea to apply user-defined rule(s) on published MQTT messages.
Case 1. ➡️ Set the threshold (or high/low watermarks) value for a specific topic. Reduce unnecessary messages.
Reviewed Web Thing API Specification to utilize events attribute to control IoT messages but not able to implement(or inject) a logic underneath with the current form.
For example,
"events": { "overheated": { "title": "Overheated", "@type": "OverheatedEvent", "type": "number", "unit": "degree celsius", ... } } Case 2. Calculate (and/or Convert) to specific format. For example, Soil Moisture Sensor generates 0~880 when the sensor is dry (~0) and when it is completely saturated with moisture (~880).
Case 3. Wildcards (+ single level,# multi level) are available but need more control over MQTT messasges?
📌 This is langualge/framework-specific example ( Eclipse mosquitto 1.5.7 MQTT broker + sqlite + lua). Therefore, the actual implemenation can be varied.
Why Lua? Lua provides simple, embeddable scripting capabilities to work with C/C++ applications. Designing DSL(Domain-Specific-Language) might be another option. Alternatively, C/C++ interpreter like Tiny C Compiler or Ch : C/C++ interpreter can be used.
Upon reviewing mosquitto sources, lib/send_publish.c is the ideal place to apply MQTT rules with minimum changes (My goal is to prove the concept rather than redesinging the existing package.) The updated version is available here.
mosquitto__rule_engine() is called from send__real_publish(). Based on topic, either no rule or user-defined lua script is executed.
int send__real_publish(struct mosquitto *mosq, uint16_t mid, const char *topic, uint32_t payloadlen, const void *payload, int qos, bool retain, bool dup) { ... // Apply rules to build "packet" if(payloadlen > 0 && mosquitto__rule_engine( topic, payload, mosquitto__packet_payload ) ) { ... handler_publish() from src/handle_publish.c manages new topic (insert new topic into topicTable if it doesn't exit). Initially it will be noaction.
$ python mqtt_rule_test.py ('Subscribing to topic', 'city/#') test_1_no_record_no_action (__main__.mqtt_rule_test) ... ('Publishing message to topic', 'city/building14/floor1/temperature') ok test_2_no_action (__main__.mqtt_rule_test) ... ('Publishing message to topic', 'city/building11/floor1/temperature') ok test_3_filter_ignore (__main__.mqtt_rule_test) ... ('Publishing message to topic', 'city/building12/floor1/temperature') ok test_4_filter_warn (__main__.mqtt_rule_test) ... ('Publishing message to topic', 'city/building12/floor1/temperature') ok test_5_convert_to_percentage (__main__.mqtt_rule_test) ... ('Publishing message to topic', 'city/building12/floor2/humidity') ok ---------------------------------------------------------------------- Ran 5 tests in 25.029s OK