-
-
Notifications
You must be signed in to change notification settings - Fork 6.7k
feat: mqtt wildcards support #6043
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 1 commit
44e36dd
9460663
cf52d47
cda7e86
67cc26e
2ba8568
67c70e0
3abbba4
81cdc6f
1979f13
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -2,6 +2,7 @@ | |||||
const { log, UP } = require("../../src/util"); | ||||||
const mqtt = require("mqtt"); | ||||||
const jsonata = require("jsonata"); | ||||||
const { regex } = require("nostr-tools/nip30"); | ||||||
CommanderStorm marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||
|
||||||
class MqttMonitorType extends MonitorType { | ||||||
name = "mqtt"; | ||||||
|
@@ -48,6 +49,19 @@ | |||||
} | ||||||
} | ||||||
|
||||||
/** | ||||||
* This function checks if the actual MQTT topic matches the subscribed topic. | ||||||
* To handle MQTT wildcards, it converts the subscribed topic into a regex pattern. | ||||||
* @param {string} subcribedTopic MQTT subscribed topic | ||||||
* @returns {RegExp} RegExp if the actual topic matches the subscribed topic | ||||||
*/ | ||||||
static mqttTopicRegex(subcribedTopic) { | ||||||
subcribedTopic = subcribedTopic.replace(/([$.|?*{}()\[\]\\])/g, '\\$1'); // Escape special regex chars except + and # | ||||||
Check failure on line 59 in server/monitor-types/mqtt.js
|
||||||
subcribedTopic = subcribedTopic.replace(/\+/g, '[^/]+'); // Replace + with regex for one or more characters except slash | ||||||
|
||||||
subcribedTopic = subcribedTopic.replace(/#/g, '.*'); // Replace # with regex for zero or more characters until next slash | ||||||
|
||||||
return new RegExp(`^${subcribedTopic}$`);; | ||||||
CommanderStorm marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
CommanderStorm marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
CommanderStorm marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||
} | ||||||
|
||||||
/** | ||||||
* Connect to MQTT Broker, subscribe to topic and receive message as String | ||||||
* @param {string} hostname Hostname / address of machine to test | ||||||
|
@@ -89,12 +103,15 @@ | |||||
clientId: "uptime-kuma_" + Math.random().toString(16).substr(2, 8) | ||||||
}); | ||||||
|
||||||
var regexTopic; | ||||||
|
var regexTopic; | |
let regexTopic; |
Copilot uses AI. Check for mistakes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NOPE here explicit usage of var
for global scope of the instance
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -100,4 +100,46 @@ | |
new Error("Message received but value is not equal to expected value, value was: [present]") | ||
); | ||
}); | ||
|
||
test('should match exact topic without wildcards', () => { | ||
const regex = MqttMonitorType.mqttTopicRegex('sensor/temperature'); | ||
assert.ok(regex.test('sensor/temperature') === true); | ||
assert.ok(regex.test('sensor/humidity') === false); | ||
}); | ||
|
||
test('should match exact topic without wildcards but with special characters', () => { | ||
const regex = MqttMonitorType.mqttTopicRegex('sensor.pomme/temperature'); | ||
assert.ok(regex.test('sensor.pomme/temperature') === true); | ||
assert.ok(regex.test('sensor.pomme/humidity') === false); | ||
}); | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please add a testcase specifically for the escaping of |
||
test('should match + wildcard for single level', () => { | ||
const regex = MqttMonitorType.mqttTopicRegex('sensor/+/temperature'); | ||
assert.ok(regex.test('sensor/room1/temperature') === true) | ||
assert.ok(regex.test('sensor/room2/temperature') === true) | ||
assert.ok(regex.test('sensor/room1/humidity') === false) | ||
assert.ok(regex.test('sensor/temperature') === false) | ||
}); | ||
|
||
test('should match # wildcard for multi-level', () => { | ||
const regex = MqttMonitorType.mqttTopicRegex('sensor/#'); | ||
assert.ok(regex.test('sensor/room1') === true); | ||
assert.ok(regex.test('sensor/room1/temperature') === true); | ||
assert.ok(regex.test('sensor/') === true); | ||
assert.ok(regex.test('actuator/room1') === false); | ||
}); | ||
|
||
test('should combine + and # wildcards', () => { | ||
const regex = MqttMonitorType.mqttTopicRegex('sensor/+/status/#'); | ||
assert.ok(regex.test('sensor/room1/status/online') === true); | ||
assert.ok(regex.test('sensor/room2/status/offline/extra') === true); | ||
assert.ok(regex.test('sensor/status') === false); | ||
assert.ok(regex.test('sensor/room1') === false); | ||
}); | ||
|
||
test('should escape special regex characters in topic', () => { | ||
const regex = MqttMonitorType.mqttTopicRegex('some.topic/+/value$'); | ||
assert.ok(regex.test('some.topic/abc/value$') === true); | ||
assert.ok(regex.test('some.topic/abc/value') === false); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MQtt and nostr don't seem really connected.
Can you add a comment explaining this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wrong import, auto import from vs-code ...