Python3 Binding (Discussion)

But the second exception log clearly says that pythonscripting could not be initialized:

java.lang.NoClassDefFoundError: Could not initialize class org.openhab.automation.pythonscripting.internal.PythonScriptEngine

It is now confirmed, jsscripting and pythonscripting can’t run in parallel in openhab4. You have to wait until openhab5 is released in 10 days where this is fixed.

If someone wants to test a new ā€œpreviewā€ version for openhab 5.x.

The new version comes with the following new features.

  1. Support for venv setups
  2. Support for ā€˜pip’ and preinstalled ā€œmodulesā€
  3. Support for native modules
  4. OSGI Console support
    4.1. You can show python scripting state values
    4.2. You can open an interactive console
    4.3. You can install, check, list and uninstall additional modules

Here is the download link

How to activate venv is described here

This version will NOT be part of openhab 5.0. It will be merged later as part of openhab 5.1

available pip commands

@Michdo93

1 Like

Another new release.

This time with support for check/list/updating helper lib module

Additionally there are jar/kar files for openhab4 and openhab5

I am making my first steps with the Python3 binding. As a start I installed the 5.0.0.0 add-on version, not the beta.

I need some Persistence values. I am using this code:

	foreCastItem = Registry.getItem("bothSides_forecast")
	logger.info(str(foreCastItem.getPersistence()))
	foreCastData = foreCastItem.getPersistence().getAllStatesBetween(startDate,startDate.plusDays(3))

It is just about 142 states to get from the Persistence database, which is working without a problem in JS or via HTTP. My code here stucks at the last line with ~390% CPU load on the raspi for 12min now, system is getting unstable because of the high load.

Is there something wrong with my implementation?

I was able to reproduce it. There is a small bug in the helper lib. It affects all functions of PersistenceExtension which results a list of HistoricItems

You can fix this by changing this line => result to _result

Or you can manual install a newer helper lib version manually by downloading the git project and copy the content of src/ to your lib/openhab/ folder. In the newer helper lib, it was already fixed.

But I will not include this version in the upcoming release, because it has already a feature freeze and it affects only the scenarios with the history item list.

The following code works for me.

from openhab import Registry
from datetime import datetime, timedelta

item = Registry.getItem("pGF_Livingroom_Air_Sensor_Temperature_Value")

endDate = datetime.now()
startDate = endDate - timedelta(days=14)

data = item.getPersistence().getAllStatesBetween(startDate,endDate)
print(data)

I tested it with mapdb which gives me just one result back. But also with jdbc which gave me 1764 items back.


btw. the next beta version (marketplace version) of this binding makes it much more easier, to update the helper lib.

1 Like

A new bugfix release is available for

openhab4 and openhab5

Changelog is

  • Update helper lib to version v1.0.1
  • Fix datetime (with and without timezone) usage as function parameter
  • Fix and generalize type mapping between java and python
1 Like

One thing I discovered: I installed the openhab5 release version (not the newer ones).
I got error wanting to
from openhab import Item
It did not find it, I looked in the __init__.py where Item is not imported from openhab.helper. I had to add it there. Is this intended?

As I was playing around and trying different things, I don’t remember (and cannot look at my code right now) whether I need it in the end, given that I can always use Registry.getItem(...), but as this class is mentioned in the docs, I just did not understand how to import it… Maybe an example would help.

Normally there is no need to import it directly. You always get it as a result of Registry.getItem calls. Also all follow up calls to PersistanceExtensions etc. are already wrapping this Item. The only scenario where you need it is, if you have a Item.java based object and this should never happen.

Can you explain me the scenario why you need to import it. If I have a better understanding of your usecase, I can provide a better API.

In the __init__.py file I ā€œforwardedā€ only rule, logger, Registry & Timer to make the import statement shorter.

from openhab import Registry can be rewritten as from openhab.helper import Registry

also from openhab.helper import Item works. But I guess you don’t really need it.

If you just want to explore the code, just take a look lib/openhab/helper.py

----- UPDATE ----

I changed to README, to explain the how and why.

I will try tonight. As I said, maybe there is no need and it was just a stupid trial… We will see.

1 Like

OK, I could not find the line in the code. Seems that I tried something, and afterwards changed to Registry.getItem…

Sorry for the confusion, I just thought if this class is mentioned just after the Registry class, it should be importable in the same way. I noticed your additions to the docs, now it’s much clearer, thanks, others (and also me) will have their benefit from that!

I have to come back to the timezone issues.

My setup: fresh openHABian installation, 64bit, openHAB 5.0.0.M4.

TimeZone setting in the WebUI is Europe/Berlin.

In Linux I correctly got:

openhabian@openhabian:/etc/openhab $ date
Do 17. Jul 15:01:41 CEST 2025

My simple Python code is:

print(ZonedDateTime.now())
print(datetime.now())

which gives

15:08:36.965[INFO] [org.openhab.automation.pythonscripting.schaltTimer.py] - 2025-07-17T13:08:36.964398121Z[GMT]
15:08:36.969[INFO] [org.openhab.automation.pythonscripting.schaltTimer.py] - 2025-07-17 13:08:36.965000

What can I do to adjust timezone correctly? In runtime.cfg, I added the explicit timezone setting, but does that need a restart of openHAB?

The only part where I can help you is with the python part.

datetime.now() is always without a timezone. But it is the local time. Not UTC.

If you want a timezone included, you have to use datetime.now().astimezone()

the seconds problem, I can just guess. ZonedDateTime.now() is not related to pythonscripting, because it shows how the timezone is configured on the opanhab java side. Can you check your openhab logs for something like

2025-07-17 14:25:51.728 [INFO ] [org.openhab.core.Activator          ] - Starting openHAB 5.0.0.M4 (Milestone Build)
2025-07-17 14:25:51.841 [INFO ] [.core.internal.i18n.I18nProviderImpl] - Time zone set to 'Europe/Berlin'.
2025-07-17 14:25:51.846 [INFO ] [.core.internal.i18n.I18nProviderImpl] - Locale set to 'de_DE'.

I configure this in conf/services/runtime.cfg like

org.openhab.i18n:language=de
org.openhab.i18n:region=DE
org.openhab.i18n:timezone=Europe/Berlin

but you can also configure this via the webui in settings => regional settings

with these settings, you script shows me.

2025-07-17 15:42:50.600 [INFO ] [b.automation.pythonscripting.test.py] - 2025-07-17T15:42:50.600523987+02:00[Europe/Berlin]
2025-07-17 15:42:50.601 [INFO ] [b.automation.pythonscripting.test.py] - 2025-07-17 15:42:50.600000

and if I used datetime.now().astimezone() it shows me

2025-07-17 15:43:48.328 [INFO ] [b.automation.pythonscripting.test.py] - 2025-07-17 15:43:48.327000+02:00

and, yes. You have ton restart openhab to activate changes in runtime.cfg. Changes in the web ui, I’m not sure if this needs a restart.

The thing is: region and timezone have been configured correctly from the start. In Linux shell, this is confirmed.
Nevertheless, local time shown by datetime is wrong (two hours behind) and zoned time has also the wrong timezone wrong (showing GMT).

EDIT:

Have restarted openHAB for the runtime.cfg to be used for sure.

2025-07-17 16:00:14.845 [INFO ] [org.openhab.core.Activator          ] - Starting openHAB 5.0.0.M4 (Milestone Build)

2025-07-17 16:00:17.245 [INFO ] [.core.internal.i18n.I18nProviderImpl] - Time zone set to 'Europe/Berlin'.

2025-07-17 16:00:17.288 [INFO ] [.core.internal.i18n.I18nProviderImpl] - Location set to '48.80758747737487,9.163320522704455'.

2025-07-17 16:00:17.299 [INFO ] [.core.internal.i18n.I18nProviderImpl] - Locale set to 'de_DE'.

2025-07-17 16:00:17.301 [INFO ] [.core.internal.i18n.I18nProviderImpl] - Measurement system set to 'SI'.

Still, my Python code:

print(ZonedDateTime.now())
print(datetime.now())

gives


16:07:25.453[INFO] [org.openhab.automation.pythonscripting.schaltTimer.py] - 2025-07-17T14:07:25.451421003Z[GMT]
16:07:25.461[INFO] [org.openhab.automation.pythonscripting.schaltTimer.py] - 2025-07-17 14:07:25.456000

If you have configured the timezone in runtime.cfg, It should also be visible in the webui.

Secondly, I would check if you get the wrong behavior in javascript too.

If you can confirm it this way, that openhab itself does not recognize the correct timezone, I would create a new thread here, just about setting the timezone.

btw. What is your timezone? Can you show me the timezone identifier?

See my EDIT above.

My timezone is Europe/Berlin (see above, OH starts stating it correctly).

In Javascript, this code:

console.log(time.ZonedDateTime.now());

gives

16:13:25.637[INFO] [org.openhab.automation.script.file.fahrten.js] - 2025-07-17T16:13:25.616+02:00[Europe/Berlin]

Python, however, is assuming the wrong timezone, namely GMT, see above.

thats strange, the following python code is just triggering java. If this already shows a wrong timezone, it looks like your JVM is not configured correctly. I’m neartly 100% sure, that this is not related to python, because it is a java function call.

from java.time import ZonedDateTime
print(ZonedDateTime.now())

the same javascript code would look like

const javaZDT = Java.type('java.time.ZonedDateTime');
console.log(javaZDT.now())

but anyway. we still have to find a way how to fix… I checked the javascript implementation related to your code

console.log(time.ZonedDateTime.now());

and this is doing it completely different. This is a Javascript Joda Class. Not a java class. Before they are initialize the Joda class with the following code (I converted it to python)

from openhab.services import getService
timeZoneProvider = getService('org.openhab.core.i18n.TimeZoneProvider');
print(timeZoneProvider.getTimeZone().getId())

can you show me the output here?

This way to initialize is directly reading the configured timezone value of openhab. It does not rely on a proper configured JVM.

I could do it in the same way. But this is just fixing 50% of the usecases. Because the pythonscripting binding depends on a proper configured JVM timezone.

e.g. you call a function with the parameter datetime.now(). On the java side the parameter has to be converted to a ZonedDateTime. For that I need the correct user timezone on the java side.


another idea… can you check that openhab is started with the parameter -Duser.timezone=Europe/Berlin. This is the way how the JVM is started with the correct timezone.

just call ps -alx| grep openhab and search for the parameter string

@rlkoshak I just ping you, because I’m a bit lost. It looks like that openhab got the correct timezone configured, but not the JVM itself. Maybe you have an idea.

— Update —
If all of that is not successful too, I have an idea how to refactor pythonscripting in a way that I depend only on the TimeZoneProvider

17:23:44.952[INFO] [org.openhab.core.automation.module.script.rulesupport.loader.AbstractScriptFileWatcher] - (Re-)Loading script '/etc/openhab/automation/python/schaltTimer.py'

17:24:01.538[INFO] [org.openhab.automation.pythonscripting.schaltTimer.py] - Europe/Berlin

With
ps -alx| grep openhab | grep timezone

I find


-Duser.timezone=Europe/London

So looks like that the JVM is not initialized correctly and that JS Scripting does not notice it because of its Joda time class.

I hope this helps - I myself honestly am lost.

One thing I realize is that you configured 2 different timezones. Berlin & London. Maybe this ist the reason why the JVM timezone is ignored.