This is a very important real-world requirement that should not easily be dismissed or ignored simply because of to the current internal structuring of OpenRemote’s MQTT extensions. As @adrianocarvalhodtx mentioned, keeping power requirements low is often extremely important for some systems. In addition to that, cellular systems are more often than not billed by the MB (if not the KB)–so every “little” savings becomes very substantial.
Especially if there are several hundred attributes to update. It’s even worse if each Attribute is 1-3 characters (think “Byte” status, 0-255): the overhead of the MQTT topic string alone at >80 bytes per Attribute simply cannot be ignored. (This isn’t even including all of the network stack overhead.)
I am tinkering with an implementation modification to the “DefaultMqttHandler” that hopefully could be an upgrade to the current default, providing the oft-requested extensibility of being able to update more than one Attribute with a single MQTT Publish.
As of right now, I do see where the Attribute permissions are tied to the MQTT topic. (The result of the permissions query is cached to reduce database queries–but said cache is also tied to the MQTT topic.)
My plan:
- Implement a slightly different endpoint, namely “writeattributevalues” (i.e. just plural, not singular), where the “{attributeName}” part of the topic is omitted (only 4 topic tokens, not 5). In other words, “{realm}/{clientID}/writeattributevalues/{assetID}”.
- All “root level” JSON keys are treated as AttributeNames, with any value (including JSON arrays and objects) being assigned to said Attribute.
- If the named Attribute cannot be found in the specified Asset, it is ignored. (This avoids database clogging with unspecified JSON payloads.)
- We have to bypass the “authorizeEventWrite” functionality in “canPublish”, as there is no “{attributeName}” in the topic. This means that any Publish request is granted, providing the User has sufficient permissions to access the Asset.
- It is relatively trivial to semi-duplicate the “authorizationCache” implementation in the JSON root key iterator loop: check for cached authorization on each existing Attribute. If not found, then confer with “authorizeEventWrite” (append the Attribute name to the “key”) → save the result to the “authorizationCache” for the following time.
So far, I’ve gotten everything except the secondary “authorizationCache” step implemented. Here’s a test with the following:
- topic: master/mqttx_xxxxxxxx/writeattributevalues/3mEmxDh7VyCSnmbRFHCEoV
- publish: {“notes”: “Idle”, “battery”: 38.12, “cells”: {“vals”: [13,0,98,2,6]}, “void”:0}
(note that I added several of these Attributes in the UI for test purposes)
Here’s the console output:
After I get the permissions per topic re-implemented (with caching) in the JSON iterator loop, is this something that could be considered as a PR for upstream OpenRemote?