[SOLVED] [MQTT] How to send integer value to a dimmer?

I had a couple of minutes so ran the test myself.

When the %d is supplied to Outgoing Value Format along with the min and max values. It publishes the floating point value. But if you supply the following JS outgoing transformation it will round the value to the nearest int.

// Wrap everything in a function
(function(i) {
    if(isNaN(i)) return -1;
    return Math.round(i)
})(input)
// input variable contains data passed by openhab

I’ll file an issue on this as I would have expected the outgoing value format to work. I don’t know it it just doesn’t work at all or it doesn’t work with this specific channel type.

1 Like

If I recall, “outgoing format” applies to the string fed into “outgoing transformation”. I presume that is the case whether you have your own transformationPatternOut or this implied transform with min/max. i.e. it does not affect final output unless not transformed.

Based on my experiment that isn’t happening here either. If I change that JS transformation to just return i instead of rounding it, it publishes 127.5. And if it only supports %s, it’s a pretty useless field.

But the description of Outgoing Value Format says:

Format a value before it is published to the MQTT broker.

And at the end of the description it says:

If you want to adjust the precision of a number to for example 4 digits, you would use “%.4f”.

So %d should be supported. But it looks like Outgoing Value Format only applies when there is nothing else modifying the outgoing message. If that’s the case, I argue it’s a huge missed opportunity. It’s also inconsistent as the Absolute minimum/maximum is applied before the Outgoing Value Transformation is called. It is inconsistant for Outgoing Value Format to not be called at all. It is ambiguous given the current docs as to whether one should expect Outgoing Value Format or Transformation to apply first, but the intuitive expectation is that either or both should be executed if supplied. Not have one just silently skipped.

No matter how you look at it, this needs more documentation.

That description needs substantial revision if it only transforms the value before the outgoing transformation or else it does nothing at all.

NOTE: I also tested with %.2f to see if I could get an extra 0 tacked on to the end and there isn’t. The OVF is not being applied at all.

Description of Outgoing Value Format may have become ambiguous now because it pre-dates the addition of “real” outwards transformation.

I just ran a test with only the OVF defined to %.2f and nothing happened (i.e. “50” was published when I commanded the Item to 50). OVF appears to be completely broken, at least for Percent type Channels.

Another test. “Foo %s” does work. So the description is way way wrong. It looks like it only works with %s which is definitely counter to what the description says.

Thank you all for your interest in that problem even though I am not totally sure to understand if there is a solution.

To answer your question the Min, Max work well and the published value is 127.5 for a brightness of 50% even with %d in OVF

To make the problem even harder, one of the dimmer device I am trying to control requires a more complex output in the form {“dps”: 2, “set”: %s} where %s is the brightness integer value between 0 and 255.

When adding {“dps”: 2, “set”: %s} in the Outgoing value format I have the proper output payload except that the dimmer value is not an integer (for example {“dps”: 2, “set”: 127.5} for a brightness value of 50%) but when I tried to use {“dps”: 2, “set”: %d}, as recommended by zorglub, I only got 127.5 as an output, the rest of the string got lost.

So it seems that there is 2 problems to sort out with %d in Outgoing value format

You’ll need a javascript outwards transformation as you want to both do some maths and some JSON encoding.
An example

I will do as rossko57 recommend but am I correct to say that if OVF was working as expected the simplest answer to my problem will be to set OVF to {“dps”: 2, “set”: %d} rather than to go the javascript outwards transformation?

I don’t know. It is not clear what order they are supposed to be evaluated. Maybe, maybe not.

I do not think so. There is a design choice about doing it before or after other transforms. Logically, if you are performing other transforms then you don’t need to to format it further afterwards. I would expect the choice to be - format first, transform after. It would be equally sensible to ignore format if applying a transform.

I would expect the following order:

  1. custom on/open off/closed absolute min/max etc
  2. outgoing transformations
  3. outgoing formatting

This would provide the most flexibility over all. It also feels more consistent with how transformations and formatting works with Items. When you look at Items, the raw data comes from the binding, flows to a transformation, and then can be formatted in the label. Here the raw value comes from the command, flows to a transformation, and finally get’s formatted.

Is there overlap between the transformation and the formatting? Of course. But having access to both lets you simplify the transformations, sometimes significantly, for several use cases I can think of. In this particular case, it lets you do the math and round it to an int without the need for a transform at all.

I agree with Rich.

Anyhow the following Javascript transform does work for my specific setup

(function(brightness) {
    var tuyaobj = {"dps": 2, "set": Math.floor(brightness)};
    var data = JSON.stringify(tuyaobj);
    return data;
})(input)

Thank you all for your help

I see this is an older topic but for me still actual.
I like to control the brightness of tradfri lightbulb, in OH3 and UI with MQTT.
Brughtness needs to be integer 0-255, Dimmer sends 0.00…-0.9999.
Where to put this function?
How to address this function?
How to use transformation?
Thanks in advance for some help!
Best regards
Piet

Maybe this might help?

Dear hafniumzinc, thanks, this helped a lot.
Major problem was I’ve chosen numbertype instead of percentage, and with creation of model changed number to dimmer. This resulted in publishing 0.99 when pointed to 99 on the scale from 0 to 254.==>brighness of bulb ± 1%

Still have issue: Publish 254 when pointing on 100 on the scale of 0 to 254 gives brightness of 100%.
Is there a solution to get a scale from 0% to 100% and publishing 254 when pointing to 100% ?

Did you carefully do this bit from that tutorial?

We have to make one small adjustment to the Item created for the Dimmer Channel:

Items → PorchLight_Dimmer → Add Metadata → State Description

Min: 0
Max: 100
Click Save top-right.

Dear Hafniumzinc, SOLVED !!

Thanks a lot !!

Best regards
Piet

What am I missing here? My problem seems to be the same. I have added the “state description” “min/max” and configured my channel as follows. Setting the dimmer to 50 in Openhab3 will only send 0,1 to MQTT

UID: mqtt:topic:cb609d2f95
label: Hue White Ambiance 1
thingTypeUID: mqtt:topic
configuration: {}
bridgeUID: mqtt:broker:e90f42a7f8
location: Kitchen Island
channels:
  - id: state
    channelTypeUID: mqtt:string
    label: state
    description: null
    configuration:
      commandTopic: zigbee2mqtt/0x001788010830795c/set/brightness
      postCommand: true
      step: 1
      min: 0
      stateTopic: zigbee2mqtt/0x001788010830795c/brightness
      max: 255

Thanks in advance

You’re using a String type Channel for a dimmer? Is that deliberate? If not, you will need to delete this Channel and create a new one - you can’t change the type of an existing Channel via the UI.

It was a mistake. I deleted the channels and recreated the thing/item/channel with this configuration:

  - id: state
    channelTypeUID: mqtt:switch
    label: state
    description: ""
    configuration:
      commandTopic: zigbee2mqtt/0x001788010830795c/set/state
      stateTopic: zigbee2mqtt/0x001788010830795c/state
      off: OFF
      on: ON
  - id: brightness
    channelTypeUID: mqtt:dimmer
    label: brightness
    description: ""
    configuration:
      commandTopic: zigbee2mqtt/0x001788010830795c/set/brightness
      min: 0
      stateTopic: zigbee2mqtt/0x001788010830795c/brightness
      max: 254
      off: OFF
      on: ON

Now everything works as intended

Thanks