OpenBK7231T_App icon indicating copy to clipboard operation
OpenBK7231T_App copied to clipboard

[enhancement] Allow MQTT topic rewriting

Open analystcmyk opened this issue 2 years ago • 9 comments

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 newTopic as a currentTopic
  • you can issue multiple rewrite commands

analystcmyk avatar Nov 14 '23 08:11 analystcmyk

Hmmmm arent you referring to this? image Third argument set to 1?

openshwprojects avatar Nov 14 '23 08:11 openshwprojects

Ok, will check that first.

analystcmyk avatar Nov 14 '23 08:11 analystcmyk

Ok yes this is working fine.

addEventHandler OnChannelChange 2 publish hasp/plate/command/p0b5.val $CH2 1

analystcmyk avatar Nov 14 '23 09:11 analystcmyk

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

openshwprojects avatar Nov 14 '23 11:11 openshwprojects

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

analystcmyk avatar Nov 14 '23 14:11 analystcmyk

So it would send that JSON to obk?

No problem, I can make a custom driver for that

openshwprojects avatar Nov 14 '23 20:11 openshwprojects

A bit like this

image

and with the mqttTopicRewrite command:

mqttTopicRewrite OBK_DEV_NAME/3/set hasp/plate/state/p1b200 $.val

meaning:

  1. subscribe to hasp/plate/state/p1b200
  2. on change copy any value from hasp/plate/state/p1b200 to OBK_DEV_NAME/3/set
  3. but since it is JSON we parse it and pick the $.val part

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:

  1. if you publish 230 to OBK_DEV_NAME/voltage/get
  2. then also publish to whatever/topic/whateverpath
  3. but since we provide the (optional) jsonPath $.val, wrap 230 in JSON and publish {"val":230}
  4. 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

analystcmyk avatar Nov 15 '23 13:11 analystcmyk

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.

Angel0ffDeath avatar Dec 28 '23 18:12 Angel0ffDeath

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 AddChangeHandler to further process and publish the data to any other topic with publish /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.

analystcmyk avatar Apr 30 '24 08:04 analystcmyk