[CLOSED] MQTT binding version 2.4 (Pre-release !)

Simply that it doesn’t work using openHAB 2.4.0 Build #1445, unless I’ve misunderstood which fixes are present in this build.

When creating a percentage channel with a JS transform that returns INCREASE or DECREASE I get the following message in the logs:

2018-11-28 23:47:50.447 [WARN ] [eneric.internal.generic.ChannelState] - Incoming payload 'INCREASE' not supported by type 'NumberValue': null

Oh ok. That surely doesn’t work. I mean the commands, you can link a dimmer item to that channel and use the increase decrease button.

I never thought of people expecting that strings should be interpreted for a number channel. It could as well be “+” or “-” then. Have to think about it. I don’t really like the idea tbh, that adds two string comparisons to each received number.

Cheers David

Indeed. I think the channel modelling might need some more thought. Did you have a reason as to why the MQTT channels aren’t aligned to OH Item types? Was this a conscious decision?

Stepping back a bit, what I’m trying to achieve is to be able to accept an INCREASE or DECREASE command from a MQTT topic and send it to a Dimmer Item.

Now, in the MQTT binding there is no channel types for Dimmer, only for Percentage or Number. As they are, the percentage or number channels work if I’m trying to set a brightness level e.g. 50% or 0.5 but as you can see are unable to accept the INCREASE and DECREASE command.

From a command point of view, the OH documentation shows us which commands each item type can receive and at the moment we obviously don’t have full coverage.

Do you think it would be prudent to model the MQTT channels in alignment with the OH Item types? Would that allow us to reuse the helper methods that validate and/or convert states? e.g. from memory something like OnOffType.ON.getAs(PercentType.class)

@David_Graeff

@cedcox’s comment give me the hint, although his Thing isn’t quite properly formatted - should be

Thing mqtt:topic:mything "Generic MQTT Thing 2"

Changed the textual configuration of my broker from a Thing to a Bridge then added the generic MQTT Thing but removed the broker from it. The documentation should be changed to something like this?:

Bridge mqtt:broker:myUnsecureBroker [ host="192.168.0.42",secure="OFF" ]
{
    Thing mqtt:topic:mything {
    Channels:
        Type switch : lamp "Kitchen Lamp" [ mqttstate="lamp/enabled", mqttcommand="lamp/enabled/set" ]
        Type switch : fancylamp "Fancy Lamp" [ mqttstate="fancy/lamp/state", mqttcommand="fancy/lamp/command", on="i-am-on", off="i-am-off" ]
        Type string : alarmpanel "Alarm system" [ mqttstate="alarm/panel/state", mqttcommand="alarm/panel/set", allowedStates="ARMED_HOME,ARMED_AWAY,UNARMED" ]
        Type color : lampcolor "Kitchen Lamp color" [ mqttstate="lamp/color", mqttcommand="lamp/color/set", rgb=true ]
        Type dimmer : blind "Blind" [ mqttstate="blind/state", mqttcommand="blind/set", min=0, max=5, step=1 ]
    }
}

Thanks for all the work on this binding!

1 Like

@g_g_rich
Hello,
Happy to help you :slightly_smiling_face:

When i use your syntax :

I have this log :

Validation issues found in configuration model 'mqttsnips.things', using it anyway:
Provide a thing type ID and a thing ID in this format:
<thingTypeId> <thingId>

it’s for that i use my syntax Thing topic mything .

But indeed, the format string of channel is not the same when created by paperui than created with this syntax :thinking:.

I’m on openHab since less than one week, so i am always in discover mode :joy:

Ced

I’m currently running build 1446 and still having this issue:
When I send a message to a percentage channel I’ve got the error ‘Value must be between 0 and 100’.
The only value’s that works are ‘0’ and 1 but when I send ‘1’ the percentage goes to ‘100’!
@David_Graeff Can U please have a look to the error logs?

@David_Graeff, thank you for your work on this binding. Do I understand that it will work with autoconfiguration of devices that follow the Home Assistant standard. I am looking at using EspHomelib with some of my ESP 8266/32 devices.

Currently it is expecting a decimal number e.g 0.5 as 50%, 0.1 as 10%.

To be honest, I do not have time to check the build number, but according to the shown log message you are not using the version with the latest MQTT fix. I have checked the number channel with decimals and whole numbers as well as the dimmer channel with min/max set to decimals and whole numbers and even added an automatic test to catch any newly introduced regressions.

In the new version there is no exception shown anymore if a value is not recognised.

Cheers, David

Originally there was only one channel planned, a String channel. For Homie/Home Assistant support I required a Boolean / Number support anyway so added the now known additional channel types.

Those types are for absolute value assignment only and were not intended to interpret commands, purely because those generic mqtt channels are for interacting with 3rd party software that does not known anything about OH.

At the moment the code receives an mqtt value, tries to assign it to the corresponding channel type and hand it over to the framework. I would need a command parsing layer with a lot of string comparisons. And most people will not benefit from this extra work done behind the scenes. So I do not intend to add this functionality.

But I do think that your idea can be realised anyway with MQTT 2.4. You would use the Trigger channel of your Broker Bridge Think. Create a script that parses your custom increase/decrease strings and use updateChannel() to update it to the newly calculated value. You could also use postCommand(…) but that would need some work/new code in the binding to handle an INCREASE/DESCREASE command coming from the framework (not from MQTT).

Cheers, David

Maybe I haven’t communicated myself properly. I wasn’t asking for a generic command parser to be implemented - I’m happy enough to parse the MQTT message in a JS transform and return an ESH state/command to be passed to the linked Item. The issue I’m having is that due to the custom validation in the Values class, some (valid from an ESH point of view) commands/states are being rejected.

My idea would be that this validation uses the existing ESH code that accepts a string and converts it into a normal ESH commands/states.

@David_Graeff Is there a chance to send a zero byte payload?
I did not find any information about this option…

I added a device using https://esphomelib.com/esphomeyaml/guides/getting_started_command_line.html.

MQTT correctly identified and added the device. I see events for it. I configured a simple switch. When controlling the device MQTT is send true/false to control the device rather than ON/OFF

I had the same problem and just entered NULL as the payload in the channel config. Works for me so far (using it with a Sonoff/Tasmota)

A transformation always returns a string. The binding does not receive a ESH command, it really just receives a string. And that need to be parsed again with the implications that I mentioned.

There is no such framework “parser” or method, that I know of that takes a State for example an OnOffState and a string to compute the new state. If such a method would exist the code would be so much easier. You mean something like the following?:

OnOffState state = ...
OnOffState newState = framework.apply(state, "ON");

Usually a binding will receive some data, process it and call the updateState() method with the channel name and appropriate ESH state e.g.

State newState ... // some binding specific processing updateState(CHANNEL_BRIGHTNESS, newState)

The flow I’m looking for is:

public void handleMqttPayload(String mqttPayload) {
    String mqttPayload = ... // data received from MQTT
    String newStateAsString = mqttPayload;
    if (transformationService != null) {
         newStateAsString = transformService.transform(newStateAsString);
    } 
     
    State newState = frameworkMethodToConvertStringToState(newStateAsString);
    updateState(CHANNEL_BRIGHTNESS, newState);
}

My understanding is that at least in the OH DSL, there is some code that converts a string representation e.g. "ON" to the OnOffType.ON

In my use case I would like my JavaScript transform to process the received JSON and return "INCREASE" or "DECREASE" which then gets sent onwards as either IncreaseDecreaseType.Increase or IncreaseDecreaseType.Decrease as a command to the channel.

I’m with you. But your mentioned frameworkMethodToConvertStringToState is what unfortunately is not existing in the Java API, I’d be happy if someone can correct me on this.

You are also a little bit confusing command and state here. INCREASE is a command and need to be applied to an already existing state (for example a number state) which of course only works on a subset of states… What happens if the old state is a string state though.

The method you a are looking for would need to take the old state, a string that hopefully converts into a command (what if multiple commands match a string?) And creates a new state that than can be propagated to the framework.

Without this method the state need to be created “by hand” though.

Cheers David

Well oke, that was a reply on an old post…
I’ve installed the latest build yet, but the issue still exists.
I have a generic mqtt thing with 2 channels:
1 On/Off switch linked to a switch item
1 Percentage value linked to a dimmer item

The percentage channel config:

When I changed the brightness from openHAB to 75 the command payload is 75, that’s oke.
My bridge which receives this command updates the state through the state topic by publishing 75 (the received command).
In openHAB I see an error:

2018-12-03 11:47:36.503 [WARN ] [eneric.internal.generic.ChannelState] - Incoming payload '75' not supported by type 'NumberValue': Value must be between 0 and 100

It only works correctly with decimal values eg 0.75, but that’s weird because of the command value of 75.
So for me, it’s still a bug.

Does it work if you use the Number channel instead of the Percentage channel?

@Kai are you able to point us to the code that enables the rules DSL to do things like sendCommand("myItemName", "INCREASE") and postUpdate("myItemName", "75") please? I’d like to see how it validates the value in relation to the item type.