Git Product home page Git Product logo

ohj's Introduction

This repo is now archived, as it has been merged into OpenHAB: https://github.com/openhab/openhab-js/


Build Status

Openhab Javascript Library

This library aims to be a fairly high-level ES6 library to support automation in Openhab.

API Documentation

Requirements

  • ES6 (e.g. GraalJS)
  • CommonJS support

Installation

  • Install the Openhab 'Experimental Rule Engine' in Paper UI
  • Install the GraalJS bundle to upgrade JS runtime to ES6
  • Ensure that you have created the automation scripting directories
  • Go to the javascript community lib directory: cd $OPENHAB_CONF/automation/lib/javascript/community
  • npm i ohj (you may need to install npm)

Usage

You should create scripts in $OPENHAB_CONF/automation/jsr223/javascript/personal.

The API can be imported as a standard CommonJS module: require('ohj'). The ohj module itself has various sections that can be imported as properties of the primary import, e.g.

//use destructing
const { rules, triggers } = require('ohj');
//or simply
const rules = require('ohj').rules;

Fluent API

The fluent section of the API can be used to write rules in a high-level, readable style.

The cleanest way to use the API is with a with statement. This is so that it's possible to use the exported functions without a prefix. An alternative approach (to allow 'use strict') would be to explicitly import the functions that you use, such as const {when, then} = require('ohj').fluent. The following examples will use the with style of importing.

Note that for the timeOfDay API, you must create a vTimeOfDay String item, which is updated like in the Openhab pattern. A future release will check this.

Fluent Examples

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

    //turn on the kitchen light at SUNSET
    when(timeOfDay("SUNSET")).then(sendOn().toItem("KitchenLight"));

    //turn off the kitchen light at 9PM
    when(cron("0 0 21 * * ?")).then(sendOff().toItem("KitchenLight"));

    //set the colour of the hall light to pink at 9PM
    when(cron("0 0 21 * * ?")).then(send("300,100,100").toItem("HallLight")

    //when the switch S1 status changes to ON, then turn on the HallLight
    when(item('S1').changed().toOn()).then(sendOn().toItem('HallLight'));

    //when the HallLight colour changes pink, if the function fn returns true, then toggle the state of the OutsideLight
    when(item('HallLight').changed().to("300,100,100")).if(fn).then(sendToggle().toItem('OutsideLight'));
}

//and some rules which can be toggled by the items created in the 'gRules' Group:

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

    //when the HallLight receives a command, send the same command to the KitchenLight
    when(item('HallLight').receivedCommand()).then(sendIt().toItem('KitchenLight'));
 
    //when the HallLight is updated to ON, make sure that BedroomLight1 is set to the same state as the BedroomLight2
    when(item('HallLight').receivedUpdate()).then(copyState().fromItem('BedroomLight1').toItem('BedroomLight2'));

    //when the BedroomLight1 is changed, run a custom function
    when(item('BedroomLight1').changed()).then(() => {
        // do stuff
    });
}

ohj's People

Contributors

jpg0 avatar dependabot[bot] avatar simonihmig avatar

Stargazers

Mike P. Kuhl avatar  avatar Philipp Waller avatar Jan Wolf avatar Michele Pinto avatar Jamie Temple avatar

Watchers

Nils Schnabel avatar  avatar James Cloos avatar  avatar Jamie Temple avatar  avatar  avatar Dupont pol-henri avatar

ohj's Issues

Issues after upgrading to OH 2.5.1-2

My scripts have all started to fail to load - which I believe is related to (accidentally) upgrading to OH 2.5.1-2

Everything was working on 2.5.0, then I did an apt upgrade and found myself on 2.5.1-2 and now nothing works :(

I get errors like this loading all of my scripts:

[ERROR] [ript.internal.ScriptEngineManagerImpl] - Error during evaluation of script 'file:/etc/openhab2/automation/jsr223/javascript/personal/motion_spare_bedroom.js': org.graalvm.polyglot.PolyglotException: TypeError: Cannot read property 'extend' of undefined

... I've pulled the latest code from here, and also used the zip of graaljs from the other thread.

... I've also tried reverting to the npm build, and the "standard" graaljs jar

help!

Update README.md to highlight OH 2.5 requirement

Hello,

So this looks like a huge improvement on the current JS library, so I thought I'd have a go this evening ... unfortunately, it looks like I can't just drop the GraalJS bundle into my addons folder - as it complains:

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) ~[?:?]

... I'm guessing that I can't play with things until I update to 2.5 (a job I'm saving for the xmas break :)

Jamie.

Openhab 3 w. ohj module installed - No IntelliSense in VS code within rules

Hi,

maybe an easy question: I'm right now moving from nashorn to graal including rewritting my rules and helpers. I will use ohj module to reduce some of the migration efforts.
To edit my scripts I'm using VS code. I noticed, that there is no IntelliSense when I'm editing my rules while there is when creating helpers.

Any suggestion to get intellisense w. JSDOC working for rules? Here is my folder structure:
grafik

Async rules not supported?

Note: I am not sure if that issue really belongs here, or somewhere upstream. If I should open this elsewhere, then please tell me.

I wanted to put a delay into a rule, but this somehow does not seem to work, neither

setTimeout(() => logger.info(`delay end`, 100);

nor

await new Promise(resolve => setTimeout(resolve, 100));
logger.info(`delay end`, 100);

... seem to execute anything that comes after the timeout. As if the VM shuts down the execution of the script.

This is unfortunate, as the need for delays will pop up quite often I guess. I have no idea how the Java and GraalVM side of things work, so don't want to speculate on what's happening or how to fix this. But in case the JS execution is indeed terminated as soon as the rule's execute function synchronously returns, then maybe it should at least be made "promise-aware", so at least the second example above would work?

Figure out approach to get this code back to openhab-scripters

Hey @openhab-5iver I wanted to point this repo out to you. I ultimately gave up trying to maintain backwards compatibility with the existing JS libraries due to a few reasons:

  • It's really hard!
  • It severely hamstrings new code
  • The existing libraries don't translate well to modules, as they assume things exist or that isolation doesn't
  • The existing libraries I would characterise as an awesome investigation into how to do most things with JS in OH (and @lewie clearly did the hard yards to get it all working), but their current state is very messy, with a mixture of styles and idioms, logging in various places put in to debug their development, and masses of commented out code. They have been a very solid foundation for me to use, but ultimately I decided that it was better to use their logic and ideas than the code directly.

The code in this repo can happily co-exist with any other scripting code, as it's just a module that can be installed with npm i ohj then used. However I'd love to contribute it back at some point if you think it's worth it (I'm completely aware that it currently lacks docs etc). Anyway, wanted to point it out to you so that you could see the direction that I've been going.

Fails on latest OH 3.0.0

I tried to get your latest 3.0.0 snapshot of the scripting addon running with my existing scripts. I updated ohj to the latest commit on master.

Still getting this exception:

14:01:08.144 [WARN ] [g.internal.OpenhabGraalJSScriptEngine] - Failed to retrieve script script dependency listener from engine bindings. Script dependency tracking will be disabled.
14:01:10.003 [WARN ] [script.js.osgi                       ] - bc=undefined		[osgi at source <unknown>, line 53]
14:01:10.032 [WARN ] [script.js.osgi                       ] - Failed to get service org.openhab.core.items.MetadataRegistry: [object Error]		[osgi at source <unknown>, line 53]
14:01:10.050 [WARN ] [script.js.osgi                       ] - Failed to get service org.eclipse.smarthome.core.items.MetadataRegistry: [object Error]		[osgi at source <unknown>, line 53]
14:01:10.108 [ERROR] [ab.automation.script.javascript.stack] - Failed to execute script:
org.graalvm.polyglot.PolyglotException: Error: Failed to get any services of type(s): org.openhab.core.items.MetadataRegistry,org.eclipse.smarthome.core.items.MetadataRegistry
	at <js>.getService(/openhab/conf/automation/lib/javascript/personal/node_modules/ohj/osgi.js:72) ~[?:?]
	at <js>.:anonymous(/openhab/conf/automation/lib/javascript/personal/node_modules/ohj/metadata/metadata.js:13) ~[?:?]
	at <js>.:anonymous(/openhab/conf/automation/lib/javascript/personal/node_modules/ohj/items/managed.js:6) ~[?:?]
	at <js>.:anonymous(/openhab/conf/automation/lib/javascript/personal/node_modules/ohj/items/items.js:8) ~[?:?]
	at <js>.:anonymous(/openhab/conf/automation/lib/javascript/personal/node_modules/ohj/rules.js:11) ~[?:?]
	at <js>.get rules(/openhab/conf/automation/lib/javascript/personal/node_modules/ohj/index.js:13) ~[?:?]
	at <js>.:program(<eval>:1) ~[?:?]
	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 org.openhab.automation.jsscripting.internal.scriptengine.DelegatingScriptEngineWithInvocable.eval(DelegatingScriptEngineWithInvocable.java:51) ~[bundleFile:?]
	at org.openhab.automation.jsscripting.internal.scriptengine.InvocationInterceptingScriptEngineWithInvocable.eval(InvocationInterceptingScriptEngineWithInvocable.java:78) ~[bundleFile:?]
	at org.openhab.automation.jsscripting.internal.scriptengine.DelegatingScriptEngineWithInvocable.eval(DelegatingScriptEngineWithInvocable.java:51) ~[bundleFile:?]
	at org.openhab.automation.jsscripting.internal.scriptengine.InvocationInterceptingScriptEngineWithInvocable.eval(InvocationInterceptingScriptEngineWithInvocable.java:78) [bundleFile:?]
	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:191) [bundleFile:?]
	at org.openhab.core.automation.module.script.rulesupport.internal.loader.ScriptFileWatcher.processWatchEvent(ScriptFileWatcher.java:157) [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) [?:?]

Note that the logged bundleContext is undefined!

Is it working for you (I assume that looking at your oh-config repo), and if so, what did I miss?

Can't get it to work

Hey, first thanks for working on this! Really looking forward to be able to write rules in modern JavaScript! ๐Ÿ˜

Unfortunately I am struggling to get this to work. I tried first with how it is described in the Readme, but get this error with a simple test rule upon requiring ohj:

Error during evaluation of script 'file:/openhab/conf/automation/jsr223/javascript/personal/test.js': org.graalvm.polyglot.PolyglotException: Object: Module not found: log

Seems this is caused by

const log = require('log').Logger('fluent');
(which should be ../log)

I am able to require from other modules like lodash without any errors in the log. So at least the GraalVM integration seems to work.

I then realized the published version on npm is quite outdated, so I tried the current master branch (copying the repo into /conf/automation/lib/javascript/community/ohj and installing deps). But then I get this one:

Error during evaluation of script 'file:/openhab/conf/automation/jsr223/javascript/personal/test.js': org.graalvm.polyglot.PolyglotException: Object: Module not found: @runtime/osgi

Not really following how these special (non-existing) @runtime modules are supposed to work?

I am using the jar linked from the Readme, with Openhab 2.5.6.

OHItem.postUpdate fails when passing DecimalType as value

I'm stuck with an issue related to GraalJS in general I guess. When I pass a DecimalType to postUpdate method of an OHItem, it fails:

TypeError: invokeMember (postUpdate) on org.openhab.core.automation.module.script.internal.defaultscope.ScriptBusEvent@30bd1bf7 failed due to: Multiple applicable overloads found for method name postUpdate (candidates: [Method[public java.lang.Object org.openhab.core.automation.module.script.internal.defaultscope.ScriptBusEvent.postUpdate(org.openhab.core.items.Item,java.lang.Number)], Method[public java.lang.Object org.openhab.core.automation.module.script.internal.defaultscope.ScriptBusEvent.postUpdate(org.openhab.core.items.Item,org.openhab.core.types.State)]], arguments: [JavaObject[RatedLuxLevel5MinAverage (Type=NumberItem, State=0 lx, Label=Rated Lux level average, Category=sun, Tags=[Measurement, Light], Groups=[gAussenHelligkeit, gLichtsensor, gVirtualSensor]) (org.openhab.core.library.items.NumberItem)] (HostObject), JavaObject[0 (org.openhab.core.library.types.DecimalType)] (HostObject)]): TypeError: invokeMember (postUpdate) on org.openhab.core.automation.module.script.internal.defaultscope.ScriptBusEvent@30bd1bf7 failed due to: Multiple applicable overloads found for method name postUpdate (candidates: [Method[public java.lang.Object org.openhab.core.automation.module.script.internal.defaultscope.ScriptBusEvent.postUpdate(org.openhab.core.items.Item,java.lang.Number)], Method[public java.lang.Object org.openhab.core.automation.module.script.internal.defaultscope.ScriptBusEvent.postUpdate(org.openhab.core.items.Item,org.openhab.core.types.State)]], arguments: [JavaObject[RatedLuxLevel5MinAverage (Type=NumberItem, State=0 lx, Label=Rated Lux level average, Category=sun, Tags=[Measurement, Light], Groups=[gAussenHelligkeit, gLichtsensor, gVirtualSensor]) (org.openhab.core.library.items.NumberItem)] (HostObject), JavaObject[0 (org.openhab.core.library.types.DecimalType)] (HostObject)])

I was running through GraalJs documentation and found the ability to specific the method signature, but that is also not helping:
TypeError: events["postUpdate(org.openhab.core.items.Item,org.openhab.core.types.State)"] is not a function: TypeError: events["postUpdate(org.openhab.core.items.Item,org.openhab.core.types.State)"] is not a function

Any idea?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.