If you say it works with native python, you can also test it with your native graalpy binary from /venv/bin/graalpy.
I already found out that the script tries to read the file .lgd-nfy0 and I already set an environment variable so that the file is put into the temp folder of openhab and has the owner and group set to the openhab user and file permissions are set to 644.
I just tried a simple test script in the pythonscripting console and I have the same error when executing those two lines:
file = open(â/openhab/userdata/tmp/.lgd-nfy0â, ârbâ)
file.read(16)
The .lgd-nfy0 file is a pipe file that is created from the native library and it has always the size 0. Could there be a problem reading those files in GraalPy?
yes, it could.
With that way, you can confirm that it is a graalpy problem.
Iâve just tested this with /venv/bin/graalpy (logged in as user openhab) and there is no error when executing the following line:
from adafruit_servokit import ServoKit
The same line in the pythonscripting console throws the error.
What could be different when GraalPy is running inside OpenHab that could cause this problem?
Edit: When launching with /venv/bin/graalpy I also had a second problem with the Adafruit_PureIO/smbus.py file. But I was able to fix this issue. This was the error message:
Traceback (most recent call last):
File "<internal>", line 1, in <module>
File "/openhab/userdata/Test.py", line 4, in <module>
File "/openhab/userdata/cache/org.openhab.automation.pythonscripting/venv/lib/python3.11/site-packages/adafruit_servokit.py", line 91, in __init__
File "/openhab/userdata/cache/org.openhab.automation.pythonscripting/venv/lib/python3.11/site-packages/adafruit_pca9685.py", line 177, in frequency
File "/openhab/userdata/cache/org.openhab.automation.pythonscripting/venv/lib/python3.11/site-packages/adafruit_register/i2c_struct.py", line 81, in __get__
File "/openhab/userdata/cache/org.openhab.automation.pythonscripting/venv/lib/python3.11/site-packages/adafruit_bus_device/i2c_device.py", line 135, in write_then_readinto
File "/openhab/userdata/cache/org.openhab.automation.pythonscripting/venv/lib/python3.11/site-packages/busio.py", line 240, in writeto_then_readfrom
File "/openhab/userdata/cache/org.openhab.automation.pythonscripting/venv/lib/python3.11/site-packages/adafruit_blinka/microcontroller/generic_linux/i2c.py", line 98, in writeto_then_readfrom
File "/openhab/userdata/cache/org.openhab.automation.pythonscripting/venv/lib/python3.11/site-packages/Adafruit_PureIO/smbus.py", line 251, in read_i2c_block_data
File "/openhab/userdata/cache/org.openhab.automation.pythonscripting/venv/lib/python3.11/site-packages/Adafruit_PureIO/smbus.py", line 93, in make_i2c_rdwr_data
NullPointerException
java.lang.NullPointerException
at com.oracle.graal.python.builtins.modules.ctypes.memory.PointerNodes$PointerArrayToBytesNode.convert(PointerNodes.java:896)
at com.oracle.graal.python.builtins.modules.ctypes.memory.PointerNodesFactory$PointerArrayToBytesNodeGen$Inlined.execute(PointerNodesFactory.java:4597)
at com.oracle.graal.python.builtins.modules.ctypes.memory.PointerNodes$WriteBytesNode.doPointerArray(PointerNodes.java:335)
at com.oracle.graal.python.builtins.modules.ctypes.memory.PointerNodesFactory$WriteBytesNodeGen$Inlined.executeAndSpecialize(PointerNodesFactory.java:1551)
at com.oracle.graal.python.builtins.modules.ctypes.memory.PointerNodesFactory$WriteBytesNodeGen$Inlined.execute(PointerNodesFactory.java:1448)
at com.oracle.graal.python.builtins.modules.ctypes.memory.PointerNodes$WriteIntNode.doOther(PointerNodes.java:445)
at com.oracle.graal.python.builtins.modules.ctypes.memory.PointerNodesFactory$WriteIntNodeGen$Inlined.executeAndSpecialize(PointerNodesFactory.java:2210)
at com.oracle.graal.python.builtins.modules.ctypes.memory.PointerNodesFactory$WriteIntNodeGen$Inlined.execute(PointerNodesFactory.java:2178)
at com.oracle.graal.python.builtins.modules.ctypes.memory.PointerNodes$WriteIntNode.execute(PointerNodes.java:417)
I was able to fix this issue by simply reversing the two lines in the smbus.py file from:
data.msgs = msg_data
data.nmsgs = len(messages)
to
data.nmsgs = len(messages)
data.msgs = msg_data
For some reason GraalPy is not happy when pointers are set before variables ar set.
I can now control my servos using the /venv/bin/graalpy executable. But inside OpenHab I still get the OSError: [Errno 5] Illegal seek. I hope this can be fixed somehow.
good thing is that you made this simple example. I was able to reproduce it and I asked the graal devs whether something like this is supported with named pipes. Weâll see what they say.
I have good and some kind of âbadâ news.
Bad news is⊠Currently we would need to switch to native posix backend to allow reading of named pipes on linux. But this is not possible, because it brings a lot of other limitations. e.g. you canât change stdin or stdout of python contexts anymore. This means python output will never be redirected to log files. So this is not an option.
Good news is⊠a graal dev means, the reason why a posix backend would be necessary can be eliminated. In the current pure java backend, they raise an exception if they seek on a nonseekable pipe like a named pipe.
But in this special scenario they try a seek to 0 which should be possible, because they just jump to the beginning.
Long story short⊠They will provide a bugfix soon, which makes this possible in native java backend.
I am trying to port a rule from JS scripting which retrieves a solar forecast via HTTP API and then has to store it in the persistence database.
In JS, I am successfully using
var timeSeries = new items.TimeSeries(âADDâ);
timeSeries.add(PV_date, (foreCastNW + foreCastSE).toString());
items.getItem(âbothSides_forecastâ).persistence.persist(timeSeries);
In Python, I have tried:
from org.openhab.core.types import TimeSeries
ts = TimeSeries(TimeSeries.Policy.ADD)
ts.add(pv_date, str(total_power))
Registry.getItem(âbothSides_forecastâ).getPersistence().persist(ts)
With the ts.add, it says
TypeError: invalid instantiation of foreign object
What do I have to do to correctly use the TimeSeries object? Do I have to convert the timestamp to Instant myself?
The second parameter of ts.add is a State object and not a string. So the correct syntax would be
from org.openhab.core.types import TimeSeries
import scope
ts = TimeSeries(TimeSeries.Policy.ADD)
ts.add(pv_date, scope.DecimalType("2.0"))
But I will implement a generic mapping for State objects soon.
for item.postUpdate or item.sendCommand, we already have this typemapping. Means you can use values like â1.0â there.
Iâm implementing now a generic solution which converts String, Integer, Boolean and datetime objects to their related State, if a State object is needed as a parameter type. That solution would work everywhere.
So it was only about the State object, not the Instant. Great. Thanks.
Seems to work!
@schup011 could you please check this version
I implemented the State/Type conversion. So the following code should work
from org.openhab.core.types import TimeSeries
ts = TimeSeries(TimeSeries.Policy.ADD)
ts.add(pv_date, "2.0")
ts.add(pv_date, 1.0)
if this and everything else works for you, I will create another marketplace release.
I have tested this version. Installation process was still a little bumpy, needed two openhab restarts and removal of the official 5.0.0.0 binding, but that could be due to the fact that I was some seconds too late after removing the previous file to also remove the option automation = jsscripting,pythonscripting in addons.cfg. That is why (I think) the 5.0.0.0 binding was installed automatically instead of the kar file I had removed from the folder.
Anyway, works now, tested the runtime_measurement option in order to make the log silent.
Also tested the TimeSeries build up. Worked without errors, I even added integers. I could easily check timestamps of begin and end of the TimeSeries, but not whether the states are in there. Will test with real data from the PV forecast, but that needs some time as the API calls per day are very limited.
EDIT: Works. I am simply feeding the TimeSeries with the numbers and they are correctly written into the persistence database.
this happens to me too when I changed this behavior.
It was a leftover from a workaround which is not needed anymore. New versions are installable without this needed change in addons.cfg.
A new release is available for
Add-on changes
- Implement State data type mapping
- Removed Item conversion, as the Add-on works now with ârealâ items on python side
- Fix dependency watcher in case of using compiled pyc files
- Fix ScriptEngine reinitialisation (in Transformation Services) after Add-on updates
- Hopefully no âContext execution was cancelledâ Exceptions after Add-on updates anymore
- An Add-on update should work now without any exception (the old one can still raise an exception on shutdown) or openhab restart
- Additional simplification of PythonScriptEngine & GraalPythonScriptEngine (~20% less code) => easier to understand for other people
- Refactored VFS
- Update helper lib to version 1.0.5
Helper lib 1.0.5 changes
- Removed âPython => Javaâ type conversion for sendCommand and postUpdate. Is now handled inside the Add-on in a more generic way.
- Replace error message
TypeError: invalid instantiation of foreign objectwith a more helpful description likeOne of your function parameters does not match the required value type. - Initial integration tests started
I noticed that every time I change something in a Python rule, there are duplicates of .so libraries created in the venv folder. (I have nativeModules enabled)
Here is a screenshot:

Is this normal or is this an issue of the beta release?
yes, this is a normal behavior of the graalvm which I canât influence. I know that they want to change this behavior with the next major upgrade of their runtime in (September/Oktober). But I donât know in which way they change it.
Ok thanks for the hint. I just clean those files up when I restart OpenHab until this is changed.
Itâs time for a new release for openhab4 and openhab5 ![]()
In addition to many other changes, this time the python autocompletion is most interesting one
Changelog
Add-on changes
- Fix internal addon log prefix (without .py) to align with script file log prefix
- Added Type Hint Stub Generator as new console command
- Fix update check console command
- Fix âupdate install latestâ command, if a newer preview version was manuell installed
- Update helper lib to version 1.0.6
Helper lib 1.0.6 changes
- Register lifecycleTracker dispose hook only if a Timer is used
- Global ZonedDateTime to datetime conversion.
ZonedDateTime&Instantis now a registered interop_type - Add
Registry.removeItem,Item.getThings,Item.getChannels,Item.getChannelUIDs,Item.getLinks,Item.linkChannel&Item.unlinkChannel=> API documentation - Improved error logs for catched java exceptions in python.
- Fix simple rule decorator (
ruleinstead ofrule()). Both variants works now. - Preview for type hinting (autocompletion)
- BREAKING CHANGE: Changed parameter of Registry.addItem
- BREAKING CHANGE: Replace NotInitialisedException with NotFoundException for getItem, removeItem, getThing, getChannel
Another release with just fixes for openhab4 and openhab5
Add-on changes
- Type hint generator fixes
- Path handling on windows
- Fix for dictionaries
- Fix nested lists
- Fix for type parameters
- Pip console command fixed
A new release for openhab4 and openhab5 with only minor changes.
Iâm just releasing it, because I want to get the breaking change out as soon as possible.
Add-on changes
- Type hint generator fixes
- Remove instanceid from generated value representations
- Update helper lib to version 1.0.7
Helper lib 1.0.7 changed
- BREAKING CHANGE
openhab.Timerremoved.- Can be replaced with default Threading or Timer implementation.
- No need to register shutdown procedure in the lifecycleTracker anymore
- Old timer can be found as an example
Hi,
Anyone else got problem with this?
Code:
import http.client
conn = http.client.HTTPSConnection(âwww.sunet.orgâ)
print(âAAAAAâ)
conn.request(âGETâ, â/â)
print(âBBBBBâ)
r1 = conn.getresponse()
print(âCCCCCâ)
while chunk := r1.read(200):
print(âDDDDDâ)
print(repr(chunk))
Result (fails at conn.request) It works using http.client.HTTPConnection, ( no SSL )
SystemError, Option python.NativeModules is set to âtrueâ and a second GraalPy context attempted to load a native module â_cpython_unicodedataâ from path â/var/lib/openhab/.cache/org.graalvm.polyglot/python/python-home/e41832d1c8ba537cb2b83ce5a12dcd2887406294/lib/graalpy24.2/modules/_cpython_unicodedata.graalpy242-311-native-x86_64-linux.soâ. At least one context in this process runs with âIsolateNativeModulesâ set to false. Depending on the order of context creation, this means some contexts in the process cannot use native module, all other contexts must fall back and set python.NativeModules to âfalseâ to run native extensions in LLVM mode. This is recommended only for extensions included in the Python standard library. Running a 3rd party extension in LLVM mode requires a custom build of the extension and is generally discouraged due to compatibility reasons.
Traceback (most recent call last):
File ââ, line 5, in
File â/var/lib/openhab/.cache/org.graalvm.polyglot/python/python-home/e41832d1c8ba537cb2b83ce5a12dcd2887406294/lib/python3.11/http/client.pyâ, line 1294, in request
self.\_send_request(method, url, body, headers, encode_chunked)
File â/var/lib/openhab/.cache/org.graalvm.polyglot/python/python-home/e41832d1c8ba537cb2b83ce5a12dcd2887406294/lib/python3.11/http/client.pyâ, line 1340, in _send_request
self.endheaders(body, encode_chunked=encode_chunked)
File â/var/lib/openhab/.cache/org.graalvm.polyglot/python/python-home/e41832d1c8ba537cb2b83ce5a12dcd2887406294/lib/python3.11/http/client.pyâ, line 1289, in endheaders
self.\_send_output(message_body, encode_chunked=encode_chunked)
File â/var/lib/openhab/.cache/org.graalvm.polyglot/python/python-home/e41832d1c8ba537cb2b83ce5a12dcd2887406294/lib/python3.11/http/client.pyâ, line 1048, in _send_output
self.send(msg)
File â/var/lib/openhab/.cache/org.graalvm.polyglot/python/python-home/e41832d1c8ba537cb2b83ce5a12dcd2887406294/lib/python3.11/http/client.pyâ, line 986, in send
self.connect()
File â/var/lib/openhab/.cache/org.graalvm.polyglot/python/python-home/e41832d1c8ba537cb2b83ce5a12dcd2887406294/lib/python3.11/http/client.pyâ, line 1466, in connect
self.sock = self.\_context.wrap_socket(self.sock,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File â/var/lib/openhab/.cache/org.graalvm.polyglot/python/python-home/e41832d1c8ba537cb2b83ce5a12dcd2887406294/lib/python3.11/ssl.pyâ, line 518, in wrap_socket
return self.sslsocket_class.\_create(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File â/var/lib/openhab/.cache/org.graalvm.polyglot/python/python-home/e41832d1c8ba537cb2b83ce5a12dcd2887406294/lib/python3.11/ssl.pyâ, line 1049, in _create
self.server_hostname = context.\_encode_hostname(server_hostname)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File â/var/lib/openhab/.cache/org.graalvm.polyglot/python/python-home/e41832d1c8ba537cb2b83ce5a12dcd2887406294/lib/python3.11/ssl.pyâ, line 508, in _encode_hostname
return hostname.encode('idna').decode('ascii')
^^^^^^^^^^^^^^^^^^^^^^^
File â/etc/openhab/automation/python/lib/openhab/_wrapper_.pyâ, line 93, in importWrapper
return importOrg(name, globals, locals, fromlist, level)
File â/var/lib/openhab/.cache/org.graalvm.polyglot/python/python-home/e41832d1c8ba537cb2b83ce5a12dcd2887406294/lib/python3.11/encodings/idna.pyâ, line 3, in
import stringprep, re, codecs
File â/etc/openhab/automation/python/lib/openhab/_wrapper_.pyâ, line 93, in importWrapper
return importOrg(name, globals, locals, fromlist, level)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File â/var/lib/openhab/.cache/org.graalvm.polyglot/python/python-home/e41832d1c8ba537cb2b83ce5a12dcd2887406294/lib/python3.11/stringprep.pyâ, line 8, in
from unicodedata import ucd_3_2_0 as unicodedata
File â/etc/openhab/automation/python/lib/openhab/_wrapper_.pyâ, line 93, in importWrapper
return importOrg(name, globals, locals, fromlist, level)