MQTT Transitioning from oh2 to oh3? /properly define a MQTT switch item?

I’m Attempting to setup the mqtt binding on OH3, I had this working in OH2 but it seems things have changed a bit. I’ve read through the documentation and can’t find any examples of how to define my items file (maybe I missed it?, but I’ve read through more than a few times) so I’ve resorted to guessing (which never really works out).
I setup the broker connection through the web interface at settings > mqtt system broker, once that was setup an mqtt broker thing showed up in my inbox, which I then added as a thing.

here is an example of one of my mqtt items:

Switch CIRCULATIONFAN  {mqtt=">[myBroker:CONTROL/CIRCULATIONFAN/GPIO/12:command:ON:1],>[myBroker:CONTROL/CIRCULATIONFAN/GPIO/12:command:OFF:0],<[myBroker:STATUS/CIRCULATIONFAN/OUTPUT/STATE:command:ON:1],<[myBroker:STATUS/CIRCULATIONFAN/OUTPUT/STATE:command:OFF:0]"}

I changed the old definition of “myBroker” to the copied uuid from the thing I added in the ui the result looks like this:

Switch CIRCULATIONFAN  {mqtt=">[mqtt:systemBroker:Broker:CONTROL/CIRCULATIONFAN/GPIO/12:command:ON:1],>[mqtt:systemBroker:Broker:CONTROL/CIRCULATIONFAN/GPIO/12:command:OFF:0],<[mqtt:systemBroker:Broker:STATUS/CIRCULATIONFAN/OUTPUT/STATE:command:ON:1],<[mqtt:systemBroker:Broker:STATUS/CIRCULATIONFAN/OUTPUT/STATE:command:OFF:0]"}

unfortunately That didn’t work and now I’m stuck, the majority of my items are all mqtt switches like the example above.

I’d like to add, I also tried replacing mqtt= with channel= at the beginning of the declaration, which results in this error:

2021-08-17 11:21:39.644 [INFO ] [el.core.internal.ModelRepositoryImpl] - Loading model 'MQTT.items'
2021-08-17 11:21:39.661 [ERROR] [el.item.internal.GenericItemProvider] - Binding configuration of type 'channel' of item 'CIRCULATIONFAN' could not be parsed correctly.
org.openhab.core.model.item.BindingConfigParseException: ID segment '>[mqtt' contains invalid characters. Each segment of the ID must match the pattern [\w-]*.
	at org.openhab.core.model.thing.internal.GenericItemChannelLinkProvider.createItemChannelLink(GenericItemChannelLinkProvider.java:86) ~[?:?]
	at org.openhab.core.model.thing.internal.GenericItemChannelLinkProvider.processBindingConfiguration(GenericItemChannelLinkProvider.java:76) ~[?:?]
	at org.openhab.core.model.item.internal.GenericItemProvider.internalDispatchBindings(GenericItemProvider.java:372) ~[?:?]
	at org.openhab.core.model.item.internal.GenericItemProvider.internalDispatchBindings(GenericItemProvider.java:341) ~[?:?]
	at org.openhab.core.model.item.internal.GenericItemProvider.processBindingConfigsFromModel(GenericItemProvider.java:212) ~[?:?]
	at org.openhab.core.model.item.internal.GenericItemProvider.modelChanged(GenericItemProvider.java:407) ~[?:?]
	at org.openhab.core.model.core.internal.ModelRepositoryImpl.notifyListeners(ModelRepositoryImpl.java:301) ~[?:?]
	at org.openhab.core.model.core.internal.ModelRepositoryImpl.addOrRefreshModel(ModelRepositoryImpl.java:139) ~[?:?]
	at org.openhab.core.model.core.internal.folder.FolderObserver.checkFile(FolderObserver.java:249) ~[?:?]
	at org.openhab.core.model.core.internal.folder.FolderObserver.processWatchEvent(FolderObserver.java:312) ~[?:?]
	at org.openhab.core.service.WatchQueueReader.lambda$3(WatchQueueReader.java:322) ~[?:?]
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) [?:?]
	at java.util.concurrent.FutureTask.run(FutureTask.java:264) [?:?]
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304) [?:?]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?]
	at java.lang.Thread.run(Thread.java:829) [?:?]

Any help would be very much appreciated.

You should be able to move your OH2 MQTT .things and .items files over without any changes. How did you set up your things before?

That’s not how this works. The mqtt="..." is the old OH 1.x way to configure an Item to use a a given binding. That’s all gone now. All an Item can do is link to a Channel on a Thing. There is no binding specific configuration on the Items any more. All you will see for any binding is { channel="<CHANNEL ID>"}.

For most bindings the device is discovered, the Things are created and the Channels are created for you. For low level bindings like MQTT you have to do that stuff manually.

As demonstrated in the Getting Started Tutorial, once you create the Broker Thing, you then have to manually create a Generic MQTT Thing that represents the device and then for each MQTT topic that is either subscribed to or published to a Channel needs to be manually created and configured.

Once the Channels are created you link them to your Items.

I didn’t have things before, I had a file in services called mqqt.cfg
it looked like this:

#
# Define your MQTT broker connections here for use in the MQTT Binding or MQTT
# Persistence bundles. Replace <broker> with an ID you choose.
#

# URL to the MQTT broker, e.g. tcp://localhost:1883 or ssl://localhost:8883
mqtt:myBroker.url=tcp://10.0.20.2:1883

# Optional. Client id (max 23 chars) to use when connecting to the broker.
# If not provided a random default is generated.
mqtt:myBroker.clientId=OpenHABian3pi

# Optional. True or false. If set to true, allows the use of clientId values
# up to 65535 characters long. Defaults to false.
# NOTE: clientId values longer than 23 characters may not be supported by all
# MQTT servers. Check the server documentation.
#<broker>.allowLongerClientIds=false

# Optional. User id to authenticate with the broker.
<broker>.user=openhabian

# Optional. Password to authenticate with the broker.
<broker>.pwd=OpenHABIOT

# Optional. Set the quality of service level for sending messages to this broker.
# Possible values are 0 (Deliver at most once),1 (Deliver at least once) or 2
# (Deliver exactly once). Defaults to 0.
#<broker>.qos=<qos>

# Optional. True or false. Defines if the broker should retain the messages sent to
# it. Defaults to false.
myBroker.retain=True

# Optional. True or false. Defines if messages are published asynchronously or
# synchronously. Defaults to true.
#<broker>.async=<async>

# Optional. Defines the last will and testament that is sent when this client goes offline
# Format: topic:message:qos:retained <br/>
#<broker>.lwt=<last will definition>

Yep, as Rich notes you were using the 1.x binding, which was made available in OH2, but not OH3.

is there a way to do it through vs code or am I forced to use the UI? I’d really rather have all my items defined via text so that I can just copy my files later on when I inevitably end up re building my system again.

OH 3 supports text based configs for everything that could be configured via text in OH 2 which includes Items and Things. However, the recommendation since OH 2 is to be consistent. Given automatic discovery the recommendation has been to manage Things through the UI (or the Karaf console). There are some things that cannot be defined through .things files (e.g. Zwave device configuration fields cannot be changed when using .things files), the syntax is tricky and the fields are not well documented.

In short, using and supporting .things files is a huge time sink which, in my experience, uses up far more time and effort getting it set up right than the time it takes to enter the few that cannot be automatically discovered through the UI. But note that point and clicking through the UI is not the only way to create things. You also have the REST API which you can interact with directly. If you have a bunch of similar MQTT Things you can create one exemplar with point-and-click and then very quickly create the rest using copy/paste/edit/submit.

And it’s not only a time sink for you the user, it’s a huge time sink here on the forum helping people who have spend days trying to get it to work only to discover a misplaced : or they used ON when they should have used "on".

If you search the forum you should find lots and lots of example mqtt.things files. But I recommend managing Things through the API.

Note, everything created through the API is stored in plain text in /var/lib/openhab/jsondb. You can just copy those files around just like your .items files to rebuild a system.

Here are some good tutorials on setting up MQTT via the UI.

Thank you for the support, I managed to get one item working. I’m not 100% happy with it yet but it works, added the thing via ui then created an item via text in vs code. Just gotta figure out how to create the thing via things file things file.

I really like how the ui has improved vs paperui, but I have been with text based configs for years now and it’s hard to move away as I’ve become much more comfortable with that.

Despite writing those tutorials linked by @rpwong I actually still use text configuration files in my openHAB system. To convert from MQTT v1 to MQTT v2/v3 check this hidden document:

1 Like

Thank you, this is very helpful, my next mission was to find an example just like this.

alright, So I have my broker and 1 item defined in mqtt.things. It works sending commands but when receiving status back I get this error:

2021-08-17 13:47:59.077 [WARN ] [t.generic.ChannelStateTransformation] - Executing the JSONPATH-transformation failed: Invalid path '$.power' in '0'

Keep in mind I do have Json path transformation installed the payload should be either 1 or 0
this is my mqtt.things file:

Bridge mqtt:broker:MyBroker "Broker" [ host="localhost", port="1883", secure=false, username="openhabian", password="OpenHABIOT", clientID="OH3" ]
{
    Thing topic JoryHeater "Jory Heater" {
    Channels:
        Type switch : Heater [ stateTopic="STATUS/Jory_Heater/OUTPUT/STATE", commandTopic="CONTROL/Jory_Heater/GPIO/12", on="1", off="0" ]
    }
}

Most likely comes from your UI experiments.

Ah I see, Did a quick reboot. Now everything appears to be working perfectly. thank you

This topic was automatically closed 41 days after the last reply. New replies are no longer allowed.