using openHAB3.2-stable on openHABian latest release.
I have a few items, defined as Number:Temperature and want to send their values via MQTT.
So I want set up an MQTT-Thing with channels configured as mqtt:number and link the items to that channel using the “follow”-profile.
Works for number-items without UoM, but items with UoM won’t trigger a command. Only after changing the channel to mqtt:string, mqtt topics are filled with values.
It’s a feature.
An update to a Number:Temperature type Item will be in the format “21.5 °C”
If you use follow profile to ‘convert’ that into a command, it’s still “21.5 °C”
If a command like “21.5 °C” or “xyz” or “45-67-999” arrives at a number type channel, it’s likely to go wrong simply because it is not a number.
What you haven’t said is what you actually want to send out on MQTT. Handling of quantity types could be improved here, but that’s one of the difficulties. You want “21.5°C” or “21.5 °C” or “21.5” or “21.5 C” or ?
That would be the one, as it is with the original number:temperature item.
So, to be clear: a channel “number” is without UoM, whereas a item “number” is with UoM. So if i want a channel to “use” UoM, I’d have to configure it as string - and I’ll get the current UoM of an item. correct?
It might work to set the unit on the Channel and then use the formatting to add the unit back before publishing and a regex to strip it on subscription.
I think the binding assumes that what ever is on the other end of the MQTT topic doesn’t know or care about units so what that property does is strip the units off of the value before publishing and adds it to the value for subscription.
It’d be a huge work around for sure but the theory is to strip the unit off from the message itself and then have the binding add it back through transformation and formatting.
I personally have successfully used the units parameter to subscribe to a topic that just publishes a number but I want to use a Number:Temperature with °F. But I’ve never had the need to deal with units that are actually on the messages published/subscribed.
hmmm. I’ve got no problem sending the value without a UoM - as I’ve already got the correct unit “Celsius”
So, I guess the best would be to strip the value. From what I understand, that must be while “incoming value” - as the channel doesn’t know UoM? correct?
So - I tried to REGEX (^\d+(\.\d+)*$) this in “incoming value transformation” like this:
I think I need more clarity. What is the format of the messages coming in and what do you want it to be published as?
My understanding was you are receiving 21.5 °C and need to publish 21.5 °C.
I’d try a simpler REGEX (make sure you’ve got the add-on installed of course). Also, your formatting is wrong. REGEX:(.*) °C. Notice the : instead of wrapping the expression in (). All transformations in MQTT and HTTP follow that sort of format: TRANSFORM_NAME:EXPRESSION. That REGEX assumes there is a single space between the number and the °C.
OK, by setting the unit on the Channel, it will strip the units from the outgoing message for you. So the only problem is the message is coming in with the units that need to be stripped so the binging can add them back.
That makes it somewhat easier. Just the transformation will be necessary I think.
I think you mean,processing an openHAB command into an MQTT message?
Yep, there is more than one way.
Some channel types offer mini-maps like a switch on=orange off=lemon, no use here.
Outgoing value format is a simple print formatter, e.g. %s to just blurt a string version of whatever came, or %.1f to round to one decimal for a number. That blows up if it isn’t a number though.
I think this is standard java formatter, not the “enhanced” version found in state description, where you can do stuff like %.1f %unit%. In other words,I think this formatter chokes on Quantities with units if you try to treat them as numbers, just leave it as %s.
Outgoing state transformation is the generic, flexible one. Here you can use a REGEX or a JS script to do whatever is needed. With a proviso that the binding will feed whatever the command was to the transformation as a string, so if you wanted to do maths you might need to parse it back into numeric within the transformation.
I don’t know what you want, you’ve asked for both “21.5 °C” and “21.5” in your MQTT message at different points, but that’s just string manipulation.
To get it work at all, the channel must be expecting the command your Item+follow sends.
A number type channel is version-dependent whether it chokes on a quantity command with units.
A rollershutter type channel would of course just choke on “21.5 °C”, for example.
A string type channel will always work. So far as I can see this is being used as an output-to-MQTT only channel, so who cares about any other effects the choice might have.
Yes, I see that. for now in my current use case it’s MQTT-only, so it would work - but as it seems, there’s no way (yet) to use mqtt:number natively with “follow” on a Number:XXX item with the corresponding UoM.
Oh, I think it does. But you still have to get all the formatting etc. correct.
The channel “unit” parameter comes into play here as well. In previous versions, that only affected inbound messages and allowed you to add a unit so that a number type channel could update a Number:(Quantity) type Item. At 3.2 it does something to outbound MQTT messages as well - strips the unit off I think? Maybe it forces it?
It does get very confusing because all these transformations are applied in turn to every message; what happens depends on the order, that’s never been clear to me. Does the format affect the raw command before passed to a REGEX, or will it format the output of a REGEX? etc. If there is a unit=, is that first or last thing done?
I’m not sure how either of those REGEX would work. In OH REGEX transformations, the expression must match the full String, not just the part you want. Neither of those expressions match the full String. That would explain why the first one doesn’t work but I’ve no idea how the second one could work at all.
The .*? construction is a little off too. The . means any character. The * means zero or more matches. The ? means zero or one matches. But matches of what? Does that mean zero or one matches of zero or more matches of any characters?
Assuming you meant one or more using your same overall approach it would look something like:
The + means one or more. Adding the C ensures the expression matches the full String. If you want to me really thorough you can add a .* after the C in case there are newlines or something like that that need to be matched.