Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions Core/automation/lib/javascript/core/PersistenceExtensions.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,18 @@
*/
'use strict';

var PersistenceExtensions = Java.type("org.eclipse.smarthome.model.persistence.extensions.PersistenceExtensions");
// START: Backward Compatibility Header
load(Java.type("java.lang.System").getenv("OPENHAB_CONF")+'/automation/lib/javascript/core/init.js');
// END: Backward Compatibility Header



//Simplifies spelling for rules.
(function(context) {
'use strict';

var PersistenceExtensions = Java.type("org.eclipse.smarthome.model.persistence.extensions.PersistenceExtensions");


context.PersistenceExtensions = PersistenceExtensions;
context.pe = PersistenceExtensions;
Expand Down Expand Up @@ -172,4 +179,12 @@ var PersistenceExtensions = Java.type("org.eclipse.smarthome.model.persistence.e
return null;
};

})(this);
})(exports);

// START: Backward Compatibility Footer
if (typeof ___INIT_STATE___ === 'undefined') {
for (var k in exports) {
this[k] = exports[k];
}
}
// END: Backward Compatibility Footer
24 changes: 18 additions & 6 deletions Core/automation/lib/javascript/core/actions.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
'use strict';

// START: Backward Compatibility Header
load(Java.type("java.lang.System").getenv("OPENHAB_CONF")+'/automation/lib/javascript/core/init.js');
// END: Backward Compatibility Header


(function(context) {
'use strict';

var osgi = require('osgi');

var OPENHAB_CONF = Java.type("java.lang.System").getenv("OPENHAB_CONF");
load(OPENHAB_CONF + '/automation/lib/javascript/core/osgi.js');

var oh1_actions = find_services("org.openhab.core.scriptengine.action.ActionService", null) || [];
var oh2_actions = find_services("org.eclipse.smarthome.model.script.engine.action.ActionService", null) || [];
var oh1_actions = osgi.find_services("org.openhab.core.scriptengine.action.ActionService", null) || [];
var oh2_actions = osgi.find_services("org.eclipse.smarthome.model.script.engine.action.ActionService", null) || [];

oh1_actions.concat(oh2_actions).forEach(function (item, index) {
context[item.actionClass.simpleName] = item.actionClass.static;
Expand All @@ -33,4 +37,12 @@
context[item.class.simpleName] = item.class.static;
});

})(this);
})(exports);

// START: Backward Compatibility Footer
if (typeof ___INIT_STATE___ === 'undefined') {
for (var k in exports) {
this[k] = exports[k];
}
}
// END: Backward Compatibility Footer
28 changes: 23 additions & 5 deletions Core/automation/lib/javascript/core/conditions.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
*/
'use strict';

// START: Backward Compatibility Header
load(Java.type("java.lang.System").getenv("OPENHAB_CONF")+'/automation/lib/javascript/core/init.js');
// END: Backward Compatibility Header


scriptExtension.importPreset("RuleSupport");

// Get Triggers and Conditions module output
Expand All @@ -15,25 +20,38 @@ scriptExtension.importPreset("RuleSupport");
// Examles:
// see: org.eclipse.smarthome.automation.sample.extension.java.internal.WelcomeHomeRulesProvider.createLightsRule()

if(ModuleBuilder == undefined)var ModuleBuilder = Java.type("org.eclipse.smarthome.automation.core.util.ModuleBuilder");
try {
exports.ModuleBuilder = Java.type("org.eclipse.smarthome.automation.core.util.ModuleBuilder");
} catch(e) {
exports.ModuleBuilder = Java.type("org.openhab.core.automation.util.ModuleBuilder");
}


// ### stateCondition ###
var ItemStateCondition = function(itemName, state, condName){
exports.ItemStateCondition = function(itemName, state, condName){
return ModuleBuilder.createCondition().withId(getTrName(condName)).withTypeUID("core.ItemStateCondition").withConfiguration( new Configuration({
"itemName": itemName,
"operator": "=",
"state": state
})).build();
}
var stateCondition = ItemStateCondition;
exports.stateCondition = exports.ItemStateCondition;

// ### GenericCompareCondition ###
var GenericCompareCondition = function(itemName, state, operator, condName){
exports.GenericCompareCondition = function(itemName, state, operator, condName){
return ModuleBuilder.createCondition().withId(getTrName(condName)).withTypeUID("core.GenericCompareCondition").withConfiguration( new Configuration({
"itemName": itemName,
"operator": operator,// matches, ==, <, >, =<, =>
"state": state
})).build();
}
//compareCondition("itemName", OFF, "==", "condNameOfCompareCondition")
var compareCondition = GenericCompareCondition;
exports.compareCondition = exports.GenericCompareCondition;

// START: Backward Compatibility Footer
if (typeof ___INIT_STATE___ === 'undefined') {
for (var k in exports) {
this[k] = exports[k];
}
}
// END: Backward Compatibility Footer
120 changes: 120 additions & 0 deletions Core/automation/lib/javascript/core/init.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
var exports = {};
var module = {};

(function (context) {
'use strict';

var OPENHAB_CONF = Java.type("java.lang.System").getenv("OPENHAB_CONF");

var buildEngine = function (){
var ScriptEngineManager = Java.type('javax.script.ScriptEngineManager');
var factory = new ScriptEngineManager();
return factory.getEngineByName("JS");
};

var engine = buildEngine();

//(Java)Log - don't depend on standard logging as it depends on the init system
var jLog = Java.type("org.slf4j.LoggerFactory").getLogger("jsr223.javascript.init")

var init_state = (function(){
if (typeof ___INIT_STATE___ === 'undefined') {
jLog.debug("Created init runtime")
return {
require_stack: [],
loaded_modules: {}
};
} else {
return ___INIT_STATE___;
}
})();


var newContext = function (engine) {
var SimpleScriptContext = Java.type('javax.script.SimpleScriptContext');
var ScriptContext = Java.type('javax.script.ScriptContext');

var ctx = new SimpleScriptContext();
ctx.setBindings(engine.createBindings(), ScriptContext.ENGINE_SCOPE);
ctx.setAttribute("scriptExtension", scriptExtension, ScriptContext.ENGINE_SCOPE);
ctx.setAttribute("exports", exports, ScriptContext.ENGINE_SCOPE);
ctx.setAttribute("module", module, ScriptContext.ENGINE_SCOPE);
ctx.setAttribute("___INIT_STATE___", init_state, ScriptContext.ENGINE_SCOPE);

return ctx;
};

var scriptTemplate = function (id, dir) {
return 'load(Java.type("java.lang.System").getenv("OPENHAB_CONF")+"/automation/lib/javascript/core/init.js");\n' +
'load("' + OPENHAB_CONF + '/automation/lib/javascript/' + dir + "/" + id + '.js");';
};

var doLoad = function(id) {
var ctx = newContext(engine);

try { //allow personal to override modules
engine.eval(scriptTemplate(id, "personal"), ctx);
jLog.debug("loaded personal script " + id);
} catch (e) {
if (e.toString().startsWith("javax.script.ScriptException: TypeError: Cannot load script from")) { //script not there; warn only
jLog.debug("No script named " + id + " in personal; falling back to core");
} else {
jLog.error("Error loading " + id + ": " + e);
}
engine.eval(scriptTemplate(id, "core"), ctx);
jLog.debug("loaded core script " + id);
}

exports = ctx.getAttribute("exports");
jLog.debug("retrieved exports: " + Object.keys(exports));
};

context.require = function require(id) {

jLog.debug("Attempting to retreive module " + id);

// if currently requiring module 'id', return partial exports
if (init_state.require_stack.indexOf(id) >= 0) {
jLog.debug("Currently requiring module " + require_stack[require_stack.length-1] + ", returning partial exports");
return init_state.loaded_modules[id].exports;
}

// if already required module 'id', return finished exports
if (init_state.loaded_modules[id] && init_state.loaded_modules[id].exports) {
jLog.debug("Module already loaded; returning cached version");
return init_state.loaded_modules[id].exports;
}

// do the require of module 'id'
// - if currently requiring a module, push global exports/module objects into arguments.callee.modules
if (init_state.require_stack.length > 0) {
var currently_requiring_id = init_state.require_stack[require_stack.length - 1];
init_state.loaded_modules[currently_requiring_id] = {
exports: exports,
module: module
};
}

init_state.require_stack.push(id);

doLoad(id);

init_state.loaded_modules[id] = {
exports: exports,
module: module
};
init_state.require_stack.pop();

// restore last required modules' partial exports to the global space, or clear them
if (init_state.require_stack.length > 0) {
var currently_requiring_id = init_state.require_stack[init_state.require_stack.length - 1];
exports = init_state.loaded_modules[currently_requiring_id].exports;
module = init_state.loaded_modules[currently_requiring_id].module;
} else {
exports = {};
module = {};
}

return init_state.loaded_modules[id].exports;
}
})(this);
15 changes: 14 additions & 1 deletion Core/automation/lib/javascript/core/metadata.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ This library provides functions for manipulating Item Metadata.

'use strict';

// START: Backward Compatibility Header
load(Java.type("java.lang.System").getenv("OPENHAB_CONF")+'/automation/lib/javascript/core/init.js');
// END: Backward Compatibility Header


(function(context) {
'use strict';

Expand Down Expand Up @@ -242,4 +247,12 @@ This library provides functions for manipulating Item Metadata.
}
};

})(this);
})(exports);

// START: Backward Compatibility Footer
if (typeof ___INIT_STATE___ === 'undefined') {
for (var k in exports) {
this[k] = exports[k];
}
}
// END: Backward Compatibility Footer
14 changes: 13 additions & 1 deletion Core/automation/lib/javascript/core/osgi.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ This library provides functions for getting, registering, unregistering, and
finding OSGi services.
*/

// START: Backward Compatibility Header
load(Java.type("java.lang.System").getenv("OPENHAB_CONF")+'/automation/lib/javascript/core/init.js');
// END: Backward Compatibility Header

'use strict';

(function(context) {
Expand Down Expand Up @@ -65,4 +69,12 @@ finding OSGi services.
}
}

})(this);
})(exports);

// START: Backward Compatibility Footer
if (typeof ___INIT_STATE___ === 'undefined') {
for (var k in exports) {
this[k] = exports[k];
}
}
// END: Backward Compatibility Footer
35 changes: 24 additions & 11 deletions Core/automation/lib/javascript/core/rules.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,18 @@
*/
'use strict';

// START: Backward Compatibility Header
load(Java.type("java.lang.System").getenv("OPENHAB_CONF")+'/automation/lib/javascript/core/init.js');
// END: Backward Compatibility Header

scriptExtension.importPreset("RuleSupport"); //https://www.openhab.org/docs/configuration/jsr223.html#overview
scriptExtension.importPreset("RuleSimple");
scriptExtension.importPreset("RuleFactories");
scriptExtension.importPreset("default");

var OPENHAB_CONF = Java.type("java.lang.System").getenv("OPENHAB_CONF");
load(OPENHAB_CONF+'/automation/lib/javascript/core/utils.js');
load(OPENHAB_CONF+'/automation/lib/javascript/core/triggers.js');
load(OPENHAB_CONF+'/automation/lib/javascript/core/conditions.js');
var utils = require('utils');
var triggers = require('triggers');
var conditions = require('conditions');

//https://docs.oracle.com/javase/8/docs/technotes/guides/scripting/nashorn/api.html
//var StSimpleRule = Java.type("org.openhab.core.automation.module.script.rulesupport.shared.simple.SimpleRule");
Expand Down Expand Up @@ -82,19 +85,21 @@ return RuleBuilder.create(ruleDto.uid)
(function (context) {
'use strict';

var log = require('log').Logger("jsr223.javascript");

//FROM: https://community.openhab.org/t/port-jsr223-bundle-to-openhab-2/2633/171?u=lewie
//Search ruleUID = filter(lambda rule: rule.name == "Alert: TV turn off timer alert", rules.getAll())[0].UID
//ruleEngine.setEnabled(ruleUID, True)# enable rule
//ruleEngine.setEnabled(ruleUID, False)# disable rule
context.setEnabled = function (ruid, enable){ //enable rule
logInfo("################ setEnabled Line: "+__LINE__+" ################# ruid:" + ruid);
log.info("################ setEnabled Line: "+__LINE__+" ################# ruid:" + ruid);
RuleManager.setEnabled(ruid, enable);
}

context.JSRule = function (obj, line) {
try{
var ruid = uuid.randomUUID() + "-" + obj.name.replace(/[^\w]/g, "-");
logInfo("################ JSRule Line: "+__LINE__+" ################# ruid:" + ruid);
var ruid = utils.uuid.randomUUID() + "-" + obj.name.replace(/[^\w]/g, "-");
log.info("################ JSRule Line: "+__LINE__+" ################# ruid:" + ruid);
//var rule = new SimpleRule({ setUID: function(i) { uid = i; } })
var rule = new SimpleRule(){
execute: obj.execute //DOES THIS WORK? AND IF YES, WHY? => execute is found in implemented SimpleRuleActionHandler
Expand Down Expand Up @@ -122,7 +127,7 @@ return RuleBuilder.create(ruleDto.uid)
//2. OR second option, to add Rules in rulefile. Is not needed.
return rule;
}catch(err) {
context.logError("JSRule " + __LINE__ + ". obj: '" + obj + "' Error:" + err);
log.error("JSRule " + __LINE__ + ". obj: '" + obj + "' Error:" + err);
}
return null;
},
Expand All @@ -131,10 +136,10 @@ return RuleBuilder.create(ruleDto.uid)
// or org.openhab.core.automation.sample.extension.java.internal.WelcomeHomeRulesProvider
//Missing SimpleRuleActionHandler!!
context.JSRuleNew = function (obj, line) {
logInfo("################ JSRuleNew Line: "+__LINE__+" #################");
log.info("################ JSRuleNew Line: "+__LINE__+" #################");
//2. OR second option, to add Rules in rulefile. Is not needed.
var rname = obj.name ? obj.name.replace(/[^\w]/g, "-") : "nameless-generic";
var ruid = obj.uid ? obj.uid : uuid.randomUUID() + "-" + rname;
var ruid = obj.uid ? obj.uid : utils.uuid.randomUUID() + "-" + rname;
var triggers = obj.triggers ? obj.triggers : obj.getEventTrigger();
var execX = new SimpleRule(){execute: obj.execute};//Not good!!
return RuleBuilder.create(ruid)
Expand All @@ -152,4 +157,12 @@ return RuleBuilder.create(ruleDto.uid)
.build();
}

}) (this);
}) (exports);

// START: Backward Compatibility Footer
if (typeof ___INIT_STATE___ === 'undefined') {
for (var k in exports) {
this[k] = exports[k];
}
}
// END: Backward Compatibility Footer
Loading