OH4.3.M4 HTTP Binding extract data from web site

Hi All

I have finally managed to get my HTTP Binding THING online and I am getting the raw data into a STRING item:

The string data can vary greatly - can be longer, shorter, contain what I am looking for or not, contain the line more than once (unlikely, but would be interested in the last occurrence):

I am trying to find a way to retrieve the single line that I am interested in and update this to an ITEM.

The line I am interested in is:

sync time:2024/11/14 19:44:09

All I really want is the actual date and time:

2024/11/14 19:44:09

It appears that this line is updated every hour or so (can vary) and I would need to:

  1. Ignore if no data present
  2. Only read the last occurence
  3. Extract just the relevant part and update to an item of DateTime
  4. Implement a Rule to work on the new item state based on previous state etc.

Has anyone done something similar and abel to share some suggestions on best way to achieve this?

EDIT:

I have created a REGEX expression that basically gives me what I need:

((.?sync time:)(\d*\/\d*\/\d*\ \d*\:\d*\:\d*))

But when I use as a Profile I do not get any result in my item?

Thanks
Mark

show us your profile config

Thanks for the reply. I actually just got it work :slight_smile:


I had to add the .* at the end of my REGEX.

Working through the rest now.

  1. I think this should happen automatically for the REGEX binding. REGEX is often used chained to other transformations to filter out messages that don’t meet a criteria.

  2. This might prove challenging as the REGEX provided through an OH transformation does not offer the full set of REGEX capabilities and options and it behaves a little differently (e.g. it uses the first group to identify what part you want to extract from the String). I think you can cause it to start at the end by appending $ after your capture group though. If not, you might need to process this data in a Rule or SCRIPT transformation where you can access the full and standard REGEX capabilities.

    .sync time:(\d/\d*\ \d*:\d*:\d*)$.*

  3. Once you get the REGEX right this should just happen. The first matching group is what gets returned.

  4. Need more details on what specifically you mean by “work on”.

Thanks Rich

  1. If there is no data the item get updated as “empty”, so I use a Rule to ignore that update in my “real” Item
  2. Actually does only read the Last occurrence - so happy with that.
  3. Got that sorted - new to REGEX so was a bit intimidated, but got it in the end.
  4. Have a Blockly Rule which is working really nicely I think. Probable a lot that could be done “better”, but happy that I can get what I need out.

Blockly Rule triggered each time the Channel Item get changed. The rule then ensure correct values in the Main Item.

Generated Code:

var Previous_Date_Time, New_date_Time, Date_Time_Difference;


//log:set DEBUG org.openhab.automation.script.ui.SunSynk_Date_Time_Change
console.debug((['Current Value of SunSynk_Current_DateTime ',items.getItem('SunSynk_Current_DateTime').state,'Current Value of previous state is: ',event.oldItemState?.toString(),'Current Value of new state is: ',event.itemState?.toString()].join('')));
Previous_Date_Time = (time.toZDT(event.oldItemState?.toString()));
New_date_Time = (time.toZDT(event.itemState?.toString()));
console.debug((['Previous Date and Time is - ',Previous_Date_Time,' New Date and Time is - ',New_date_Time].join('')));
Date_Time_Difference = (time.ChronoUnit.MINUTES.between(Previous_Date_Time,New_date_Time));
console.debug(('Date and Time difference is (minutes) - ' + String(Date_Time_Difference)));
items.getItem('SunSynk_Time_Diff_Mins').sendCommand(Date_Time_Difference);
if (Date_Time_Difference > 2) {
  actions.notificationBuilder(('SunSynk Time Difference More than 2 minutes - ' + String(Date_Time_Difference))).withIcon('alarm').withTag('info').send()
}

Thansk for any advise etc.

If it’s a DateTime type Item I think the Item would either not be updated or updated to NULL or UNDEF. There is no such thing as an “empty” state for a DateTime Item.

However, if you need the Item to be updated to NULL or UNDEF (assuming the update is not just ignored) you can chaing the REGEX transform to a SCRIPT transform that converts blank to NULL.

JS:| (input == "") "NULL" ? input

That’s an inline transform so in the UI you would just add that as a new transform below the REGEX one. @jimtng made chaining transformations in the UI much nicer, no more strange untypeable characters required.

This is a quirk" of the way the web site I am scraping works.
The web site is a “rolling” log of events. It seems to work on a buffer type system where the page resets when the buffer fills up, so if the HTTP Binding polls the page at that specific time there is a chance (actually quite frequent) that there is no sync time:2024/11/14 19:44:09entry at all.

When this happens the REGEX linked item is updated with an empty string.

I am not interested in these empty strings - only what the most recent sync time value was.

So I need to ignore any empty updates and only process actual values.

Hence the rule that I showed above.

Happy to hear if there are any better ideas to achieve this?

Assuming the Item’s name is “Foo”

JS: | (input == '') ? items.Foo.state : input

If the REGEX returns the empty string update the Item to it’s current state.

Any rule that does something with the DateTime just needs to trigger on the Item changeing. Such rules will only trigger when there is a sync time and that time is different from the Item’s current state.