Hello,
I’m new to OpenHAB and thus I need to learn a lot of things.
Up to now I created a generic MQTT Thing which is sbuscribed to an external MQTT broker.
The MQTT Thing is linked to an Item and there I store the MQTT payload (message).
(Connection to the broker and all that works, I get the payload.)
This has the form:
R1:ON
or e.g.
R1:OFF
and other numbers instead of “1”.
No I need to extract the text after the colon “:” and I need to know the number left from the colon.
this will be only a one digit number.
I’m trying to create a rule based on DSL to extract substrings but it does not work.
Could you please help me?
Thank you in advance.
Wolfgang
Without knowing anything more about your device than what you’ve written, I would just create separate Thing Channels for each R that you have, and then in the custom on/off value options just use the payload strings.
Hi,
I’m not familiar with channels. Sorry.
I do not understand your proposal.
Is it possible to have different channels activated depending on the content of the payload?
Sorry, if the question is on low level but OpenHAB is really new for me.
Thank you.
W.
But you say you linked your Thing to an Item - you can only do that via a Thing Channel.
Yes.
I’d take a step back and have a look through the documentation, especially the Getting Started guide. That should bring you up to speed on the concepts, and there’s an MQTT example or two in there too!
I read the Getting Started section and also the MQTT example.
There they have json messages but I don’t have this.
The message is really simple like I wrote before and I have not idea how I could separate the information in various channels I have one channel and that contains the complete MQTT message.
Sending of MQTT messages is done directly in the shell with the Mosquitto publish command.
I mean I use the Mosquitto publish command to send a message. The Mosquitto publish command is to simulate the real device. In reality the message is send by a water irrigation based on an Arduino device (ESP32).
However, the payload is according to the pattern
Ah, just met…
Given a String Item mqttIn with the full payload:
rule "mqttIn auswerten"
when
Item mqttIn received update
then
val String strIn = mqttIn.state.toString
if(strIn.length < 5) {
logWarn("mqttIn","erwartete Länge verfehlt: {} ({})",strIn,strIn.length)
return;
}
val String strLetter = strIn.charAt(0)
val Integer iNumber = Integer::parseInt(strIn.charAt(1))
val Value = if(strIn.charAt(4) == "F") OFF else ON
if(strLetter != "M" && strLetter != "R") {
logWarn("mqttIn","1. Buchstabe falsch: {}",strLetter)
return;
}
if(strLetter == "M") {
switch(iNumber) {
case 1: Item1.sendCommand(Value)
case 2: Item2.sendCommand(Value)
case 3: Item3.sendCommand(Value)
case 4: Item4.sendCommand(Value)
case 5: Item5.sendCommand(Value)
case 6: Item6.sendCommand(Value)
case 7: Item7.sendCommand(Value)
case 8: Item8.sendCommand(Value)
case 9: Item9.sendCommand(Value)
}
} else {
switch(iNumber) {
case 1: Item10.sendCommand(Value)
case 2: Item11.sendCommand(Value)
case 3: Item12.sendCommand(Value)
case 4: Item13.sendCommand(Value)
case 5: Item14.sendCommand(Value)
case 6: Item15.sendCommand(Value)
case 7: Item16.sendCommand(Value)
case 8: Item17.sendCommand(Value)
case 9: Item18.sendCommand(Value)
}
}
end
Of course there are many other ways to do this, it’s up to the exact job if this solution is ok or not…
@Udo_Hartmann has actually provided an answer to your OP, but I would still do all this within Channels, not requiring a rule at all. Again, though, we don’t know much about the application, so the following solution assumes:
Your device is a relay, switching things on and off only
You have no control over the code on your Arduino device
Your MQTT topic is TEST for all messages that get sent from your Arduino device
You are controlling four (4) switches.
For the following solution, make sure the RegEx Transformation Service is installed: Settings → Bindings → Search.
Then create a Generic MQTT Thing with the following Channels:
Each Channel is of type Switch, and these are then linked through to Switch type Items.
Each Channel specifies a custom on/off value, relevant to the switch number.
To prevent warnings in the logs, the REGEX is used to filter the incoming message so only the relevant one is passed to the relevant Channel.
If there are more switches just add extra Channels.
If you do have control over the code on the Arduino device then I would just get each relay or switch to publish their on/off status on dedicated topics. For example:
myirrigationdevice/R1
You then use this in the State Topic of the relevant Channel, and you wouldn’t need the transformationPattern, on and off parameters at all.
Hello Udo,
I started first with your proposal from above. I took your code, adapted it to my Item names etc.
I did this with Visual Studio Code and having the OpenHAB language support installed there.
(I read in book that this helps to have a good code with less errors.)
Then I saved the new rule in the given folder /etc/openhab/rules and it was recognized because I also do see it in the Rules section in the Paper UI. So far so good.
In the PaperUI I can run the rule (there is a link at the bottom to do this.)
Unfortunately now I get an error in the log file saying that some method can not be invoked.
This is the error:
022-03-19 19:20:07.174 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'MQTT_Eval_In-1' failed: An error occurred during the script execution: Could not invoke method: java.lang.Integer.parseInt(java.lang.String) on instance: null in MQTT_Eval_In
Do I need to import some libraries at the start of the rule and if yes which ones?
Thank you.
Wolfgang
I did a quick test, and there is a small issue in the rule .charAt() is of Type Char, not String. So please add a .toString on every .charAt():
...
val String strIn = mqttIn.state.toString
if(strIn.length < 5) {
logWarn("mqttIn","erwartete Länge verfehlt: {} ({})",strIn,strIn.length)
return;
}
val String strLetter = strIn.charAt(0).toString
val Integer iNumber = Integer::parseInt(strIn.charAt(1).toString)
val Value = if(strIn.charAt(4).toString == "F") OFF else ON
if(strLetter != "M" && strLetter != "R") {
logWarn("mqttIn","1. Buchstabe falsch: {}",strLetter)
return;
}
// for a short test:
logInfo("mqttIn","Letter {} Number {} Value {}",strLetter,iNumber,Value)
...
Hello,
Thank you for the support again. You are great.
I inserted the ".toString method and then
I tested the rule and intentionally I 've send a MQTT message being to short and this created an error entry in the openhab log as it was supposed to do.
Now, I will check the next things.
I will keep you informed.