jpg0 / openhab-graaljs

0 stars 0 forks source link

OH3 support #1

Closed JamieTemple closed 3 years ago

JamieTemple commented 3 years ago

Hello,

Well, I feel a little unkind raising an "issue", but (unsurprisingly) this does not work with OH3.

It will come as absolutely no surprise, that I get the following error if I drop the OH2 bundle into my addons folder:

00:03:07.344 [WARN ] [org.apache.felix.fileinstall         ] - Error while starting bundle: file:/openhab/addons/org.openhab.automation.module.script.graaljs-2.5.0-SNAPSHOT.jar
org.osgi.framework.BundleException: Could not resolve module: org.openhab.automation.module.script.graaljs [257]
  Unresolved requirement: Import-Package: org.openhab.core.automation.module.script; version="[2.5.0,3.0.0)"

        at org.eclipse.osgi.container.Module.start(Module.java:444) ~[org.eclipse.osgi-3.12.100.jar:?]

... or ... I've done something stupid (quite possible!)

Am I correct assuming this bundle simply wont work? Are you working on an OH3-friendly release?

Thanks :)

jpg0 commented 3 years ago

The way OH works means that it expects all the core dependencies to have the same version, which means a version 3.0 for this plugin, and therefore the current one not working. In addition, there have been a number of package moves within OH so it's also not a simple recompile. Fortunately, there is little change in the actual APIs used so little real work.

Saying this:

I'm not sure about the stability of 3.0 yet. Have you now switched? Is it stable and working well? When I tried the UI would hardly render so I didn't make it very far.

JamieTemple commented 3 years ago
  • I did get the plugin working against 3.0, it's in the 3.0.x branch in this repo

Thanks, but I'd need lots of guidance to build this myself - I don't do any Java stuff these days (not for a looong time!)

  • At the time I did not switch my home version of OH to 3.0 because it seemed too unstable
  • So I decided to leave the 3.0.x branch as-is, then when 3.0 is sufficiently stable I would switch and also switch the version I'm working on to 3.0.x

I'm not sure about the stability of 3.0 yet. Have you now switched? Is it stable and working well? When I tried the UI would hardly render so I didn't make it very far.

The milestone builds are pretty damn good.

I played with a snapshot a while back, but probably had the same experience as you.

I run OH in a docker container, and have been running 2+3 side-by-side for over a month now without any problems - it's really allowed me to embrace the semantic tagging + new UI - which I've had no problems with at all 👍

... if it helps, here is the script that I run to sync my OH3 config with my "master" OH2 setup:

#!/bin/bash

# Copy config from OH2...
cp /var/local/containers-data/openhab/conf/icons/classic/*.*  /var/local/containers-data/openhab3/conf/icons/classic
cp /var/local/containers-data/openhab/conf/items/*.*          /var/local/containers-data/openhab3/conf/items
cp /var/local/containers-data/openhab/conf/things/*.*         /var/local/containers-data/openhab3/conf/things
cp /var/local/containers-data/openhab/conf/transform/*.*      /var/local/containers-data/openhab3/conf/transform
cp /var/local/containers-data/openhab/conf/sitemaps/*.*       /var/local/containers-data/openhab3/conf/sitemaps
cp /var/local/containers-data/openhab/conf/sounds/*.*         /var/local/containers-data/openhab3/conf/sounds
cp /var/local/containers-data/openhab/conf/services/*.*       /var/local/containers-data/openhab3/conf/services
# To copy when we switch over:
#cp /var/local/containers-data/openhab/conf/automation/*.*     /var/local/containers-data/openhab3/conf/automation
#cp /var/local/containers-data/openhab/conf/rules/*.*          /var/local/containers-data/openhab3/conf/automation
#cp /var/local/containers-data/openhab/conf/persistence/*.*    /var/local/containers-data/openhab3/conf/automation
# Not used - scripts, misc
# Not copying - html

# Update MQTT client ID so it doesnt clash with existing OH2 client config (or previous OH3 config)
random_number=$RANDOM

rn="clientID=\"OPENHAB_${random_number}\""

echo "Updating MQTT client ID to " $rn

# Note that this assumes that your MQTT bridge is defines in mqtt.things with clientID="OPENHAB"
sed -i "s/clientID=\"OpenHAB\"/${rn}/" /var/local/containers-data/openhab3/conf/things/mqtt.things

# Update Zoneminder config to use new binding
sed -i 's/="zm:/="zoneminder:/' /var/local/containers-data/openhab3/conf/items/zoneminder.items
sed -i 's/zm:server/zoneminder:server/' /var/local/containers-data/openhab3/conf/things/zoneminder.things

# Change Karaf console port number so it doesn't clash with OH2
sed -i 's/sshPort = 8101/sshPort = 8102/' /var/local/containers-data/openhab3/userdata/etc/org.apache.karaf.shell.cfg
sed -i 's/sshHost = 127.0.0.1/sshHost = 0.0.0.0/' /var/local/containers-data/openhab3/userdata/etc/org.apache.karaf.shell.cfg

# TODO: Change openhab password to something stronger
# TODO: Create ~/.ssh/authorized_keys

# Now, don't forget to install your bindings + transformation services... ;)

:)

jpg0 commented 3 years ago

I've been working on OH3 support. I have a couple more PRs to have merged before basic JS support in OH3 itself 🤞

Here are a couple of addons that should get things working if you're interested now.

Archive.zip

JamieTemple commented 3 years ago

I've been working on OH3 support. I have a couple more PRs to have merged before basic JS support in OH3 itself 🤞

I've been keeping a close eye on your PRs - noted that the first made it into the last milestone build ... basically, I've been leaving you alone on this one, as the "bigger picture" is more important than me right now ;)

Here are a couple of addons that should get things working if you're interested now.

That's brilliant - thanks - I'll play this evening.

... I did try and get things working - managed to build stuff in VS code, but really didn't know what I was doing - spent a weekend playing, then gave up and decided to be patient ;)

... will let you know how I get on (testing with the latest milestone)

JamieTemple commented 3 years ago

OK ... so I dropped the bits in the addons folder, stuck the latest v3 branch bits of ohj into an appropriate place, and started my docker container.

My scripts fail with:

19:31:23.728 [INFO ] [hab.core.service.AbstractWatchService] - Loading script '/openhab/conf/automation/jsr223/javascript/personal/lib/common.js'
19:31:23.812 [ERROR] [ab.automation.script.javascript.stack] - Failed to execute script:
org.graalvm.polyglot.PolyglotException: TypeError: invokeMember (extend) on org.openhab.automation.module.script.extension.ClassExtender@15f60fba failed due to: Unknown identifier: extend
        at <js>.:anonymous(/openhab/conf/automation/lib/javascript/personal/node_modules/ohj/log.js:18) ~[?:?]
        at <js>.:anonymous(/openhab/conf/automation/lib/javascript/personal/node_modules/ohj/osgi.js:8) ~[?:?]
        at <js>.:anonymous(/openhab/conf/automation/lib/javascript/personal/node_modules/ohj/items/managed.js:3) ~[?:?]
        at <js>.:anonymous(/openhab/conf/automation/lib/javascript/personal/node_modules/ohj/items/items.js:8) ~[?:?]
        at <js>.get items(/openhab/conf/automation/lib/javascript/personal/node_modules/ohj/index.js:14) ~[?:?]
        at <js>.:program(common.js:12) ~[?:?]
        at org.graalvm.polyglot.Context.eval(Context.java:345) ~[?:?]
        at com.oracle.truffle.js.scriptengine.GraalJSScriptEngine.eval(GraalJSScriptEngine.java:379) ~[?:?]
        at com.oracle.truffle.js.scriptengine.GraalJSScriptEngine.eval(GraalJSScriptEngine.java:343) ~[?:?]
        at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:249) ~[java.scripting:?]
        at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
        at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?]
        at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
        at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?]
        at org.openhab.automation.module.script.graaljs.internal.commonjs.graaljs.GraalJSCommonJSScriptEngine.lambda$4(GraalJSCommonJSScriptEngine.java:144) ~[?:?]
        at com.sun.proxy.$Proxy1432.eval(Unknown Source) ~[?:?]
        at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
        at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?]
        at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
        at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?]
        at org.openhab.automation.module.script.graaljs.internal.DebuggingGraalScriptEngine.lambda$1(DebuggingGraalScriptEngine.java:76) ~[bundleFile:?]
        at org.openhab.automation.module.script.graaljs.internal.DebuggingGraalScriptEngine.withStackLogger(DebuggingGraalScriptEngine.java:101) [bundleFile:?]
        at org.openhab.automation.module.script.graaljs.internal.DebuggingGraalScriptEngine.lambda$0(DebuggingGraalScriptEngine.java:76) [bundleFile:?]
        at com.sun.proxy.$Proxy1432.eval(Unknown Source) [?:?]
        at org.openhab.core.automation.module.script.internal.ScriptEngineManagerImpl.loadScript(ScriptEngineManagerImpl.java:170) [bundleFile:?]
        at org.openhab.core.automation.module.script.rulesupport.internal.loader.ScriptFileWatcher.importFile(ScriptFileWatcher.java:183) [bundleFile:?]
        at org.openhab.core.automation.module.script.rulesupport.internal.loader.ScriptFileWatcher.checkFiles(ScriptFileWatcher.java:289) [bundleFile:?]
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) [?:?]
        at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) [?:?]
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) [?:?]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?]
        at java.lang.Thread.run(Thread.java:834) [?:?]
19:31:23.814 [ERROR] [ript.internal.ScriptEngineManagerImpl] - Error during evaluation of script 'file:/openhab/conf/automation/jsr223/javascript/personal/lib/common.js': org.graalvm.polyglot.PolyglotException: TypeError: invokeMember (extend) on org.openhab.automation.module.script.extension.ClassExtender@15f60fba failed due to: Unknown identifier: extend

... am I missing something? (probably!)

jpg0 commented 3 years ago

You're not missing something, but I was! Thanks for alerting me to it!

I typically keep all my config in a git repository with a submodule pointing at the ohj repository. Somehow (I hate submodules) I managed to remove the submodule and was committing updates to ohj to oh-config and not ohj. I've just committed the changes back to ohj (and will fix the submodule at some point).

Anyway, the upshot is that you need to update the ohj library - some of the packages in OH have changed and needed updating in ohj. Give it an update and let me know!

JamieTemple commented 3 years ago

OK - still struggling I'm afraid :(

Log looks like this:

18:17:15.837 [INFO ] [hab.core.service.AbstractWatchService] - Loading script '/openhab/conf/automation/jsr223/javascript/personal/triggers/trigger.wakeup.js'
18:17:15.862 [ERROR] [ab.automation.script.javascript.stack] - Failed to execute script:
org.graalvm.polyglot.PolyglotException: class [Ljava.lang.Object; cannot be cast to class java.lang.String ([Ljava.lang.Object; and java.lang.String are in module java.base of loader 'bootstrap')
        at org.openhab.automation.module.script.graaljs.internal.commonjs.graaljs.GraalJSCommonJSScriptEngine.lambda$3(GraalJSCommonJSScriptEngine.java:113) ~[?:?]
        at java.util.Optional.orElseGet(Optional.java:369) ~[?:?]
        at org.openhab.automation.module.script.graaljs.internal.commonjs.graaljs.GraalJSCommonJSScriptEngine.lambda$1(GraalJSCommonJSScriptEngine.java:113) ~[?:?]
        at <js>.:program(common.js:12) ~[?:?]
        at <js>.:program(trigger.wakeup.js:10) ~[?:?]
        at org.graalvm.polyglot.Context.eval(Context.java:345) ~[?:?]
        at com.oracle.truffle.js.scriptengine.GraalJSScriptEngine.eval(GraalJSScriptEngine.java:379) ~[?:?]
        at com.oracle.truffle.js.scriptengine.GraalJSScriptEngine.eval(GraalJSScriptEngine.java:343) ~[?:?]
        at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:249) ~[java.scripting:?]
        at jdk.internal.reflect.GeneratedMethodAccessor85.invoke(Unknown Source) ~[?:?]
        at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
        at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?]
        at org.openhab.automation.module.script.graaljs.internal.commonjs.graaljs.GraalJSCommonJSScriptEngine.lambda$4(GraalJSCommonJSScriptEngine.java:144) ~[?:?]
        at com.sun.proxy.$Proxy1437.eval(Unknown Source) ~[?:?]
        at jdk.internal.reflect.GeneratedMethodAccessor85.invoke(Unknown Source) ~[?:?]
        at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
        at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?]
        at org.openhab.automation.module.script.graaljs.internal.DebuggingGraalScriptEngine.lambda$1(DebuggingGraalScriptEngine.java:76) ~[bundleFile:?]
        at org.openhab.automation.module.script.graaljs.internal.DebuggingGraalScriptEngine.withStackLogger(DebuggingGraalScriptEngine.java:101) [bundleFile:?]
        at org.openhab.automation.module.script.graaljs.internal.DebuggingGraalScriptEngine.lambda$0(DebuggingGraalScriptEngine.java:76) [bundleFile:?]
        at com.sun.proxy.$Proxy1437.eval(Unknown Source) [?:?]
        at org.openhab.core.automation.module.script.internal.ScriptEngineManagerImpl.loadScript(ScriptEngineManagerImpl.java:170) [bundleFile:?]
        at org.openhab.core.automation.module.script.rulesupport.internal.loader.ScriptFileWatcher.importFile(ScriptFileWatcher.java:183) [bundleFile:?]
        at org.openhab.core.automation.module.script.rulesupport.internal.loader.ScriptFileWatcher.processWatchEvent(ScriptFileWatcher.java:149) [bundleFile:?]
        at org.openhab.core.service.WatchQueueReader.lambda$3(WatchQueueReader.java:322) [bundleFile:?]
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) [?:?]
        at java.util.concurrent.FutureTask.run(FutureTask.java:264) [?:?]
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304) [?:?]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?]
        at java.lang.Thread.run(Thread.java:834) [?:?]
18:17:15.864 [ERROR] [ript.internal.ScriptEngineManagerImpl] - Error during evaluation of script 'file:/openhab/conf/automation/jsr223/javascript/personal/triggers/trigger.wakeup.js': org.graalvm.polyglot.PolyglotException: class [Ljava.lang.Object; cannot be cast to class java.lang.String ([Ljava.lang.Object; and java.lang.String are in module java.base of loader 'bootstrap')

fyi - line 12 of common.js looks like this:

const { items } = require('ohj');

I've pulled the latest "master" branch of ohj (as that looks like what you've updated, not the 3.0.x branch)

I've had a look in here but I think I'm looking in the wrong place... :(

jpg0 commented 3 years ago

That's weird. You're doing everything right - I have switched to ohj master as the branch I'm now working against OH3.

That stack trace is saying that the GraalJS runtime is failing to convert an Object array to a String. It's as part of the module loading code. I'll take a look when I get some time; amazed that I've found any time to spend on this at this time of year tbh!

JamieTemple commented 3 years ago

seriously fella - don't fret - it's a busy time of year, and we've all got stuff on the go right now - I appreciate your help :)

... I got a message out of the blue last week from somebody that's using some software I wrote for a little-known OS (RISC OS) that I haven't touched in over 15 years ... seems like my code has been running fine right up until the last OS update in October - 15 years with no patches required!

... suffice to say, I'm having fun re-discovering an old-code-flame right now, and it'll keep me amused during the xmas downtime ... same goes for you ... have a look at this if you fancy a distraction from your festivities ... no rush ;)

JamieTemple commented 3 years ago

Not sure if this helps, but I've got a simple script:

with(require('ohj').fluent){

    const { getItem } = require('ohj').items;

    when(
        item("Debugging_Enabled").changed())
    .then((it) =>
        getItem("Echo_LastUsed_TTS").sendCommand("Open HAB debugging is now " + it.newState)
    );
}

That throws the following:

18:57:46.503 [INFO ] [hab.core.service.AbstractWatchService] - Loading script '/openhab/conf/automation/jsr223/javascript/personal/debugging.js'
18:57:46.510 [WARN ] [g.internal.OpenhabGraalJSScriptEngine] - Failed to retrieve script script dependency listener from engine bindings. Script dependency tracking will be disabled.
18:57:46.579 [WARN ] [script.js.osgi                       ] - bc=org.eclipse.osgi.internal.framework.BundleContextImpl@7f675f90                [osgi at source <unknown>, line 53]
18:57:46.616 [WARN ] [script.js.osgi                       ] - bc=org.eclipse.osgi.internal.framework.BundleContextImpl@7f675f90                [osgi at source <unknown>, line 53]
18:57:46.619 [WARN ] [script.js.osgi                       ] - bc=org.eclipse.osgi.internal.framework.BundleContextImpl@7f675f90                [osgi at source <unknown>, line 53]
18:57:46.643 [WARN ] [script.js.osgi                       ] - bc=org.eclipse.osgi.internal.framework.BundleContextImpl@7f675f90                [osgi at source <unknown>, line 53]
jpg0 commented 3 years ago

I'm about to upgrade my whole system to 3.0 so I'll chase down any bugs shortly. My testing on 3.0 has been minimal so far.

Also, the messages in your logs (bc=...) look like some left over debugging that I must have forgotten to clean up. They don't appear to suggest a problem, at least.

JamieTemple commented 3 years ago

A quick update - I've managed to get things working :) :) :)

The key issue was that the following worked in OH2.5

load(Java.type("java.lang.System").getenv("OPENHAB_CONF") + '/automation/jsr223/javascript/personal/lib/common.js');

... now I've moved my common.js into lib\javascript\personal\node_modules, turned it into a "propper" module, and replaced the offending line above with:

const { sendCommandTo, postUpdateTo, IsOn, isOff, sendOnTo, sendOffTo, stateOf, valueOf, makeAlexaSay } = require('common.js');

... and things started to work ... just needed to change every function that used the old Java DateTime class, and we're up and running again :)

... one final thing ...

this:

actions.NotificationAction.sendBroadcastNotification("my message", "temperature", "WARN");

... now does this:

TypeError: undefined has no such function "sendBroadcastNotification"
jpg0 commented 3 years ago

Not sure why the inline loading is now failing, but I hate that style anyway so I'm not too fussed!

As for your final error - it looks like actions is not defined. Are you using the ohj actions, or something else? One place I can see that I use it in my code looks like:

const { actions } = require('ohj');
actions.thingActions("telegram",`telegram:telegramBot:comms`).sendTelegram(chatId, message);
JamieTemple commented 3 years ago

Not sure why the inline loading is now failing, but I hate that style anyway so I'm not too fussed!

totally agree ;)

As for your final error - it looks like actions is not defined. Are you using the ohj actions, or something else? One place I can see that I use it in my code looks like:

const { actions } = require('ohj');
actions.thingActions("telegram",`telegram:telegramBot:comms`).sendTelegram(chatId, message);

Ok - so I figured this out - actions.js needs line 27 updating from: const oh2_actions = osgi.findServices("org.eclipse.smarthome.model.script.engine.action.ActionService", null) || []; to const oh2_actions = osgi.findServices("org.openhab.core.model.script.engine.action.ActionService", null) || [];

jpg0 commented 3 years ago

Thanks! I've added this to master now: https://github.com/jpg0/ohj/commit/f4079a4be522f860e67f38a4a7c6dfd304f8295b