RegEx - Extract Number from String hh:mm:ss

Hello,
I am struggeling extracting a number from a string item.
My Item is:

String HeatPump_Heizstab "Betriebsstunden ZWE1 [%s]" <time> (gHeatpump) { novelanheatpump="hours_zwe1" } // Laufzeit Heizstab

and it contains a string that tells in hh:mm:ss a duration 324:23:34

I would like to extract the hours as number so I could create a chart to display when the duration increased (=when the electrical heating was ON)

Therefore I created a RegEx and put that in a rule:
(basically a copy from the RegEx help: https://www.openhab.org/addons/transformations/regex/)

    rule "Convert String to Item Number"
	when
		Item SwitchButton changed 
	then
		// use the transformation service to retrieve the value
		val newValue = transform("REGEX", "^\\d+?(?=:)", HeatPump_Heizstab.state.toString)

		// post the new value to the Number Item
		Num_Heizstab_Dauer.postUpdate( newValue )
	end

Just the item Num_Heizstab_Dauer remains NULL - I would have expected it to be 324
Testing the RegEx in the online tools like regex101 did actually work?!

could anyone please help?!

I suspect that you may be getting errors in your openhab.log file that would help you to understand the issue. Another thing that could help you is to add your own log entries from the rule itself. For example, after assigning the value to your new variable, check to see what the value is, to make sure you are getting what you expect…

logWarn("Test", "newValue: {}", newValue)

REGEX works a little different in OH, unfortunately. Firstly, the pattern must match the entire string. Secondly, the first group is what gets returned. So you nee a pattern more along the lines of

^(\\d+):.*

I’ve had some weirdness using \d in the past so you might need to use

^([0-9]+):.*

That is above and beyond what ever error is causing the transformation not to run in the first place which, as mentioned, the logs should help you figure out.

Hello Scott,
thanks for your reply - it appears I should more often take a look into the logs :slight_smile: I did find quite some entries that helped me clean up my code a bit - AND I did find the entry you mentioned but I do not really understand what it tries me to tell?!:

2020-12-01 10:17:09.552 [WARN ] [rthome.model.script.actions.BusEvent] - Cannot convert 'null' to a state type which item 'Num_Heizstab_Dauer' accepts: [DecimalType, QuantityType, UnDefType].
2020-12-01 10:17:09.558 [WARN ] [.eclipse.smarthome.model.script.Test] - newValue: {}

could you again help me?

The warning is saying that newValue is null, which is not a compatible type for updating Num_Heizstab_Dauer with. So, the next step is to figure out why newValue is null. As Rich mentioned, the REGEX TransformationService needs a pattern that will match the whole string, and it will only return a match to the first capture group. Your data is composed of numbers and colons, so start by matching everything…

.*

You are looking to have the first set of digits returned, stopping at the first colon, so add a capture group at the beginning that grabs a variable number of digits…

([0-9]+).*

Rich’s example gets more specific, by only matching strings that start with our capture group (the string starts with what we are after, so we already have that) and stopping the capture group at a colon (it already stops at anything that is not a digit), but these are not necessary. Hope this helps!

Hello Scott, Hello Rich,

thanks for your help! Actually both of your answers led to the solution.
Several lessons learnt:

  1. Read the logs - even if you think things are “ok” but definetely if you encounter an issue!!
  2. Carefully read Rich’s explanations. The part of

“…match the entire string…”

I did read it but did not really understand until Scott elaborated on that again!

So my issue was that I also removed the :.* from Rich’s statement which caused the bad log entry.

Now the working solution is:

rule "Convert String to Item Number"
when
	Item HeatPump_Heizstab changed
then
	// use the transformation service to retrieve the value
	val newValue = transform("REGEX", "^([0-9]+):.*", HeatPump_Heizstab.state.toString)

	// post the new value to the Number Item
	Num_Heizstab_Dauer.postUpdate( newValue )
end

Again - Thanks so much for your help!!

1 Like