Skip to content
This repository was archived by the owner on Nov 16, 2020. It is now read-only.

phyunsj/mqtt-rule-engine

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

24 Commits
 
 
 
 
 
 

Repository files navigation

MQTT Rule Engine

Introduction

Exploring an idea to apply user-defined rule(s) on published MQTT messages.

Rule

Case 1. ➡️ Set the threshold (or high/low watermarks) value for a specific topic. Reduce unnecessary messages.

Alt Text A: Read Sensor;A -> B: "85" Temperature F;B->x B:;Sensor -> A:;A -> B: "95";B->x B:;Sensor -> A:;A -> B: "110";B -> C: if temp > "100" F;@enduml;" style="max-width: 100%;" loading="lazy" onerror="this.onerror=null,this.src='/assets/placeholder.svg'">

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).

Alt Text A:Read Sensor;A -> B: "345" Range 0-2047;B -> C: { "moisture" : "17"};@enduml;" style="max-width: 100%;" loading="lazy" onerror="this.onerror=null,this.src='/assets/placeholder.svg'">

Case 3. Wildcards (+ single level,# multi level) are available but need more control over MQTT messasges?

Alt Text A:Read Sensor ;A -> B: "110" Temperature F;B -> C: "110" Temperature F;create "Subscriber B";B --> "Subscriber B": warning if temp > 100 F ;@enduml" style="max-width: 100%;" loading="lazy" onerror="this.onerror=null,this.src='/assets/placeholder.svg'">

Implementation

📌 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 

Related Posts: