Use of Number:Temperature Items ... and other quantities in jython

Does anyone have any good examples of using Items with Quantity types like Temperature for jython scripts?

a simple example of, for instance how to log a Items value that has quantity without it generating errors like:

TypeError: expected string or buffer, but got <type 'org.openhab.core.library.types.QuantityType'>

or

UnicodeEncodeError: 'ascii' codec can't encode character u'\xb0' in position 3: ordinal not in range(128)

I know basically what the errors are and have been diving into docs but an example would go a long way to help me understand it.

Thanks!

For the first error I think you just need to call toString() on the QuantityType. Using the Python str() function might work too.

The second error I think has to do with the fact that Python 2.7 doesn’t support UTF by default. I can’t remember if I ever tried to log a Temperature like that back when I was using Python.

Thanks Rich. Yes I found this:

https://www.openhab.org/javadoc/latest/org/openhab/core/library/types/quantitytype

And can use the constructor xyz.intValue() or xyz.longValue() to get the magnitude of the quantity. xyz.toString() works great.

No, using str(xyz) by itself generates an error as well due to the degree symbol.

I think I should rename my Items that involve quantities (to remind me) to avoid future inadvertent errors :slight_smile:

Wait, instead of renaming your Items, why not be clever here. You could create a library function that you can call with a state. That function will convert the state to a string no matter what type of state you pass to it. In the function determine if the state is a QuantityType and handle that differently. Then you can use that function everywhere and know it will work and work the same way no matter what type of state it is.

1 Like

Brilliant. I like it. I’ve been burned on other Items as well … scratched my head a bit on being forced into having to do this:

rThermostat_SetPoint.log.info("Thermostat temp manually set to " + HeatOverrideTemp.toString() + " for " + str(int(str(items["ThermostatCT101_HeatOverrideMinutes"])) * MINUTES))

Had to convert the items["ThermostatCT101_HeatOverrideMinutes"]) to a string first, then to an int() to do the arithmetic and then to a str() to display it :slight_smile: … I didn’t spend too much time on it so I’m sure (I hope) there’s an explanation :slight_smile: (the Item is defined as a Number)

Edit: using this:

rThermostat_SetPoint.log.info("Thermostat temp manually set to " + HeatOverrideTemp.toString() + " for " + str(items["ThermostatCT101_HeatOverrideMinutes"].intValue() * MINUTES))

A Number Item’s state is of type DecimalType. A DecimalType in turn is of type Number. But neither a DecimalType nor a Number is nor is it compatible with a Python int. To do math all the operands have to be compatible. So you either need to convert your Python int to a java.lang.Number or you need to convert your DecimalType to be a Python int.

items["ThermostatCT101_HeatOverrideMinutes"] * new BigDecimal(MINUTES)

or

items["ThermostatCT101_HeatOverrideMinutes"].intValue() * MINUTES
1 Like

Cool. Never having learned Java is proving to be my weak point … where do I find things like BigDecimal? I’ll need to google … :slight_smile:

Every time you interact with OH stuff you are interacting with Java classes and Objects. If it’s generic Java stuff like ZonedDateTime you’ll look at the Javadocs: BigDecimal (Java SE 11 & JDK 11 ). If it’s openHAB specific you can find them at Overview (openHAB Core 3.2.0-SNAPSHOT API).

Notice how BigDecimal inherits from Number. That’s why I know that if I create a BigDecimal it will be compatible with the DecimalType that is the state of the Item since DecimalType also inherits from Number.

2 Likes

Thanks Rich … embarrassed to admit that my software transitions over the last 40 (wait, 50) years was:

Basic->Z80/8086 assembly->Fortran->C->more assembly->Perl->Python with a little JaveScript and various other languages I was forced to hack in … I guess it’s time to graduate into the 21st century.