Blockly: How to extract the number from an item state?

OH 3.2 on a Pi4

I want to compare a number to a given value. In my case it’s the temperature (e.g. “17 °C”) to a number (e.g. 18). I set the temperature from the item state into a variable first, however the variable will contain the unit of measure " °C". Therefore it can’t be compared to a number.

I’ve tried to get the first two letters only using the text tools but this gives a parsing error.

How do I get the number-only value of an item state so I can use it for further processing?

Thank you!

Related:

We can’t see what you’ve tried, but if this is what I think it is then you need to first force the value into a string by appending an empty string, before doing string manipulation stuff. This can all be done in Blockly, using variables and the Text blocks.

This is what I have so far. I initiate “TempSchlafzimmer” empty first, then get the Temp reading. It will be “17 °C” e.g.
Then I initiate “TempValueOnly” empty first, then try to slice the first two letters to it. This line gives me the error:

2022-03-19 23:20:19.315 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID ‘TempCheck_Fenstersensoren’ failed: TypeError: TempSchlafzimmer.slice is not a function in at line number 9

However, even if I can somehow manage to slice the temp value - both variables will be strings. How can I convert them to do maths with it? And why is this so complicated? Are there easier approaches to react on a certain measurement?

Feed your Item state into a variable first, and then use the append block (with an empty text block attached) to force the variable into a string. And then do your slicing.

:person_shrugging:

Probably. Did you try the method outlined in the post I linked?

Personally I don’t use any of the smart units stuff in openHAB - just keep everything in simple plain numbers.

1 Like

Feed your Item state into a variable first, and then use the append block (with an empty text block attached) to force the variable into a string. And then do your slicing.

This did the trick! Thank you very much. Now I can try and make a function from it and simply call it to convert my strings to numbers.

Probably. Did you try the method outlined in the post I linked?

I’ve read through it but did not get the point of methodology to use. Sorry.

Personally I don’t use any of the smart units stuff in openHAB - just keep everything in simple plain numbers.

It’s just the way those items were created automatically. And I am afraid to change them no to Number:Temperature (or something like that) not to break anything. I’ve already invested countless hours but for now OH is just a nice visual tool. Any “smart” functions you must program yourself.

It’s a limitation of the simplicity of Blockly rules scripting, for the moment.

All the other rules languages allow for handling “quantities” directly, so you can just compare apples with apples, e.g. myTemperatureItem.state > 18 °C

1 Like

Just in case someone is stumbling across this post with a similar issue, here is how I solved it:

It’s a function block that you can call anywhere in the main program to convert. It takes the input value, looks for the first " " space character, stripes off all the rest and clears any probably remaining spaces before it returns the value back.

Thank you, @hafniumzinc!

Blockly also seems to handle (at least) temperature quantities just fine for comparisons. For example, the following Number:Temperature Item:

{
  "link": "http://openhab.lan/rest/items/Pi3B_temp",
  "state": "32.71 °C",
  "stateDescription": {
    "step": 1,
    "pattern": "%s %unit%",
    "readOnly": true,
    "options": []
  },
  "editable": true,
  "type": "Number:Temperature",
  "name": "Pi3B_temp",
  "label": "temp",
  "category": "",
  "tags": [
    "Point"
  ],
  "groupNames": []
}

can be used succesfully as follows:

image

Generated code
var temp_limit;

var logger = Java.type('org.slf4j.LoggerFactory').getLogger('org.openhab.rule.' + ctx.ruleUID);


temp_limit = 15;
if (itemRegistry.getItem('Pi3B_temp').getState() > temp_limit) {
  logger.error('Temp is higher than limit');
} else {
  logger.error('Temp is lower than limit');
}

or as follows (and suggested in the thread I linked in my first post):

image

Generated code
var logger = Java.type('org.slf4j.LoggerFactory').getLogger('org.openhab.rule.' + ctx.ruleUID);

if (itemRegistry.getItem('Pi3B_temp').getState() > '15') {
  logger.error('Temp is higher than limit');
} else {
  logger.error('Temp is lower than limit');
}

So splitting the string shouldn’t be needed at all, I think @ItsaBastI.

In case it matters, I’m on openHAB 3.3.0.M2