[Solved] Extract date and time into two separate items from a string based channel/item

Hi all,

I am running OH 5.1.0 M2 as a docker container on my NAS. I just connected my new heat pump via an EMS-ESP to MQTT conversion box (BBQKees) and I have discovered the things and its channels via the HomeAssistant MQTT component of the MQTT binding.

All good !

But the channel for date/time delivers the date and time as one string in the format: 31.10.2025 20:23

I have linked the channel to a String item but I would like to have date and time in separate items but I am too stupid to get this done … In the past I did everything in the items file but I wanted to modernize my behaviour and do everything via the UI and I fail:

Here is a screenshot of the current date/time item which is in the string format

I kindly appreciate any hint and support to help me to divide the full string in two separated items for

  1. Date
  2. Time

Cheers Justus

Why not one single DateTime Item?

Since the HA MQTT Things do not support transformations, you’ll need to do the transformation in a Profile.

  1. From Settings → Transformations create a new Script transformation. The code below will be JS Scripting. The transformation will convert this String into one the DateTime Item. can understand.
(function(input){
  const split = input.split(' ');
  const zdt = time.toZDT(split[1]); // convert time to ZDT with today's date
  const dateSplit = split[0].split('.').map( s => parseInt(s));
  return zdt.withYear(dateSplit[2]).withMonth(dateSplit[1]).withDayOfMonth(dateSplit[0]).toString();
})(input)
  1. From the Channel “Add link to item”
  2. create a new item
  3. fill out all of information about this new item, making sure to change the type to DateTime
  4. At the bottom choose the script option that corresponds to the language you choose in 1.
  5. For the channel to Item field, select the transformation you created in 1.

I just typed in the code above in this posting. it has not been tested and may have errors. But the overall approach should be clear. Note the map iterates over all members of the array and creates a new array with the result of the function. I’m this case I’m using map to convert the strings to ints.

Anywhere you need just the time you can get or display the time from the DateTimeType. Same goes for the date. You didn’t need two items for that.

1 Like

Thank you Rich!

I thought that I need to keep the type as given by the source which is String. I Thought using the DateTimeType would only work when the time is given in the full format like 2025-11-01T17:04:55.000+0100because in that case you may apply the formatting like

  • %1$td for day
  • %1$tm for month
  • %1$tY for year
  • %1$tH for hours
  • %1$tM for minutes

When I choose DateTime as

I can not select the “Standard” profile anymore and I do not know what to select there to create the item

And even if I have it stored in an item with DateTime type. I would not know how to extract the date and the time as I thought the formatting codes aboove will only work if the time is provided in this full format :thinking:.

I will start trying with the transformation profile as it should transform the string into a Date/Time item and then it should be possible to extract the date and the time from it :+1:

THANK YOU FOR YOUR SUPPORT!!!

I have created a JS = javascript transformation script with the content above as is looks ok for me:

I have created a new link to an item from the thing channel and I have put the UID of the transformation script in the profile configuration’s first line “Thing to Item” (= your Channel to Item) but it does not work …

Sorry that I do not find myself through the UI but I want to learn how it works without item files.

I found this error message in the log … I am starting to debug :slight_smile:

Failed to process script 'test.js' in link 'jretest -> mqtt:homeassistant:mySecureBroker:ems_2Desp_2Dbud_2Dthermostat:thermostat_datetime': <eval>:4:47 Expected , but found =>
    var dateSplit = split[0].split(".").map( s => parseInt(s));
                                               ^ in <eval> at line number 4 at column number 47

I’m not sure where the test.js part comes from. You’ve done everything in the UI, right? That’s odd.

The syntax looks correct. input is a String. Calling split on a String gives an Array of Strings. map is a method on Arrays that iterates over each element and applies the passed in function. You can try putting the argument in the call to map in parens but I’ve never needed to do that before.

const dateSplit = split[0].split('.').map( (s) => parseInt(s));

You can also add console.info log statements temporarily to see what the result of the calls become.

During testing I created the funtion as a js script as I thought it might be related to the transformation built in the UI

test.js:

function (data) {
    var split = data.split(" ");
    var zdt = time.toZDT(split[1]); 
    var dateSplit = split[0].split(".").map( (s) => parseInt(s));
    return zdt.withYear(dateSplit[2]).withMonth(dateSplit[1]).withDayOfMonth(dateSplit[0]).toString();
} (input)

If I run it like this I still get the error:

19:45:01.212 [ERROR] [n.module.script.profile.ScriptProfile] - Failed to process script 'test.js' in link 'blatest -> mqtt:homeassistant:mySecureBroker:ems_2Desp_2Dbud_2Dthermostat:thermostat_datetime': <eval>:4:49 Expected , but found =>
    var dateSplit = split[0].split(".").map( (s) => parseInt(s));
                                                 ^ in <eval> at line number 4 at column number 49

If I leave out the map() then I don’t get an error:

function (data) {
    var split = data.split(" ");
    var zdt = time.toZDT(split[1]); 
    var dateSplit = split[0].split(".");
    return zdt.withYear(dateSplit[2]).withMonth(dateSplit[1]).withDayOfMonth(dateSplit[0]).toString();
} (input)

But the item still shows NULL

I think I will try it via items file and see how far I get … update to this probably in 24 hours.

THANK YOU Rich for trying to solve this for me!!!

Ok, the MQTT channel delivers a String and hence I can not send it to a DateTime item.

So I do not come around the effort to transform the String format into the DateTime format.

Tough learning curve for a non techie :smiley:

The problem has nothing to do with UI vs files.

The whole point of the profile is to transform the String into a format that is compatible with a DateTime Item. Just because the Channel says it needs a String Item doesn’t mean you are stuck with that type of Item.

You did not copy the code as I wrote it. You are missing the opening parenthese.

I must be as I wrote it:

(function (data) {
    var split = data.split(" ");
    var zdt = time.toZDT(split[1]); 
    var dateSplit = split[0].split(".");
    return zdt.withYear(dateSplit[2]).withMonth(dateSplit[1]).withDayOfMonth(dateSplit[0]).toString();
}) (input)

See JavaScript Scripting - Automation | openHAB for details.

@rlkoshak I have put everything in an item file

DateTime    mx400DateTime_dt		  "MX400 Datum"	        (heatpump)	{channel="mqtt:homeassistant:mySecureBroker:ems_2Desp_2Dbud_2Dthermostat:thermostat_datetime" [profile="transform:JS", toItemScript="test.js", toHandlerScript=""] }

This is the script:

(function(data) {
    const split = data.split(" ");
    const zdt = time.toZDT(split[1]); 
    //var dateSplit = split[0].split(".").map( (s) => parseInt(s));
    const dateSplit = split[0].split(".");
    return zdt.withYear(dateSplit[2]).withMonth(dateSplit[1]).withDayOfMonth(dateSplit[0]).toString();
})(input)

and now I get this error

22:10:21.222 [ERROR] [n.module.script.profile.ScriptProfile] - Failed to process script 'test.js' in link 'mx400DateTime_dt -> mqtt:homeassistant:mySecureBroker:ems_2Desp_2Dbud_2Dthermostat:thermostat_datetime': ReferenceError: "time" is not defined in <eval> at line number 3 at column number 17

Seems that time is not there :thinking:

There are changes in 5.1 M2 which allows for more choice when importing the helper library. It is supposed to default to “import for everything” but some have been noticing that it’s not being imported. It’s being looked into.

But you will either need to import what you need yourself or change the add-on setting and restart OH.

To import it yourself:

var {time} = require('openhab');

(function (data) {
    var split = data.split(" ");
    var zdt = time.toZDT(split[1]); 
    var dateSplit = split[0].split(".").map(s => parseInt(s));
    return zdt.withYear(dateSplit[2]).withMonth(dateSplit[1]).withDayOfMonth(dateSplit[0]).toString();
}) (input)

Note, I’ve now tested the above code I find it works even with the map. However, if input is NULL or UNDEF the transformation will fail. You can add a test for that.

var {time} = require('openhab');

(function (data) {
    if(data == "NULL" || data == "UNDEF") return data; 
    var split = data.split(" ");
    var zdt = time.toZDT(split[1]); 
    var dateSplit = split[0].split(".").map(s => parseInt(s));
    return zdt.withYear(dateSplit[2]).withMonth(dateSplit[1]).withDayOfMonth(dateSplit[0]).toString();
}) (input)

Or you need to go to Settings → JS Scripting → and choose Auto injection for all scripts, including file-based scripts and transformations. You need to reload all your JS scripting rules and transformations or just restart OH.

You can’t just remove the map and expect the code to work though. It’s there for a reason. Just removing it is like removing one of the wheels of your car and expecting it to go.

1 Like

WORX :clap: :clap: :clap: :clap: :clap:

THANK YOU !!! :heart_hands: