[enhancement] Allow MQTT topic rewriting
I want to use OpenHASP https://www.openhasp.com/0.7.0/ to display sensor values published by OpenBEKEN to MQTT.
OpenHASP allows the values of screen objects to be set via MQTT.
For example : by publishing 25 to hasp/plate/command/p0b5.val you update the displayed value of that object.
Issue :
OpenBEKEN publishes to a fixed topic, eg /device/power/get
I cannot instruct OpenBEKEN to publish the sensor value to hasp/plate/command/p0b5.val
Suggested :
Add command to rewrite the MQTT topic just before publishing, e.g.
mqttTopicRewrite currentTopic newTopic [keep]
mqttTopicRewrite /device/power/get hasp/plate/command/p0b5.val
The optional keep flag is to publish also to the currentTopic
Alternative :
use addEventHandler OnChannelChange 1
Related issue : https://github.com/HASwitchPlate/openHASP/issues/577
Restrictions :
- you cannot chain rewrites , i.e. use the
newTopicas acurrentTopic - you can issue multiple rewrite commands
Hmmmm arent you referring to this?
Third argument set to 1?
Ok, will check that first.
Ok yes this is working fine.
addEventHandler OnChannelChange 2 publish hasp/plate/command/p0b5.val $CH2 1
btw, it seems you are doing something very interesting. Please consider writing a tutorial/;article about it for our forum, we can send you a set of Elektroda gadgets for that
Well before that ( I am using the https://www.openhasp.com/0.7.0/hardware/sunton/esp32-2432s028/#esp32-3248s035 ) module I would like to elaborate a bit the back route from LCD module to OpenBEKEN.
Having OpenHASP to monitor/control OpenBEKEN is not a bad option. Just a dumb broker is needed to do all, no Node-RED or other dependencies.
These modules have an ESP32 so they could even run a micro MQTT server next to it. ( looking at https://github.com/tuanpmt/esp_mqtt )
To be honest I would like be able to communicate touch events to openBeken directly, but since I have limited control on what topic openHASP is publishing, you could think of a flexible way to have OpenBEKEN actually subscribe to a user defined topic. Maybe keep the (non-existing) command mqttTopicRewrite analogy.
So instead of getting the commands from OBK_DEV_NAME/INDEX/set you would say :
mqttTopicRewrite OBK_DEV_NAME/1/set Gadgetx/switch/1
Of course that is not an easy thing to do, and it would need to honour the CMD_SetChannelPrivate as well.
Monitoring multiple OBK on a single OpenHASP already works fine.
Sample button
A sample of an OpenHASP toggle button ( page 1, id 200), devicename =plate looks like this :
Channel : hasp/plate/state/p1b200 , Payload {"event":"up","val":0}
So getting that would involve parsing the JSON as well...
So it would send that JSON to obk?
No problem, I can make a custom driver for that
A bit like this
and with the mqttTopicRewrite command:
mqttTopicRewrite OBK_DEV_NAME/3/set hasp/plate/state/p1b200 $.val
meaning:
- subscribe to
hasp/plate/state/p1b200 - on change copy any value from
hasp/plate/state/p1b200toOBK_DEV_NAME/3/set - but since it is JSON we parse it and pick the
$.valpart
I think the "keep original" flag is not needed anymore and the currentTopic should always be available.
Remarks
I think mqttTopicClone is a better name, and it would mean that we may also use it for cloning mqtt publish behaviour, eg
mqttTopicClone currentTopic newTopic [jsonPath]
mqttTopicClone OBK_DEV_NAME/voltage/get whatever/topic/whateverpath $.val
meaning:
- if you publish
230toOBK_DEV_NAME/voltage/get - then also publish to
whatever/topic/whateverpath - but since we provide the (optional) jsonPath
$.val, wrap230in JSON and publish{"val":230} - in case we have no jsonPath, then the value is copied without parsing
In this way it would work transparently in both directions: Parse when receiving, Wrap when publishing
You run usually MQTT server on home automation server. I don't know what home automation you are using, but it is always possible when receive a mqtt message in one topic just to change what you want (if necessary) and publish the message into another topic. Your initial question is somehow MQTT server to receive the messages and in the same time your device, without server to do anything. Don't forget flash memory of the device is usually not so much and firmware fits barely. And firmware continues to grow, adding new devices, so it is good idea if your MQTT server can do some work instead of the device. Usually the device needs just to report the data to server. What server will do with this data and how this data will be distributed to the other devices is server job and not device job.
Ok, then maybe we could consider this : (in analogy of linkTuyaMCUOutputToChannel)
- Define a channel, eg 3, and set a type.
- Allow to subscribe to an MQTT topic and map the value to that channel, eg
linkMqttTopicToChannel /mychannel/myvar 3 - Use the
AddChangeHandlerto further process and publish the data to any other topic withpublish /myotherchannel/myothervar $CH3 -1
In this way we would use existing functions where possible and only linkMqttTopicToChannel would be a new command.
Things to consider:
- We would need to limit the number of subscribed MQTT topics.
- You would want to check that you cannot publish to that topic yourself in order to prevent looping
- It should be clear what to expect as payload and how to handle that. For example: we only accept string/int and no JSON, or we accept only values that are the same as set by
setChannelType.
Thinking about that, you might also choose to expand the setChannelType command to do this:
eg setChannelType 3 Mqtt /mytopic/myvar but since this is mainly for display purposes this may not be appropriate.
On the other hand you can use the existing channel register and it could prevent conflicts.