lucid is an openHAB jsr223 Jython helper library. It's a derivative work based on Steve Bate's great project openHab2-jython.
This project is no longer supported, please consider using openhab2-jython instead.
lucid takes openHAB Jython scripting to a higher level and can be used for general scripting purposes, including defining rules, triggers and conditions. lucid aims to be easy to use and to provide a good documentation. (The documentation work has just begun)
- Getting Started with lucid
- Defining rules using rule scripts
- Loading and reloading the Jython rule binding
- Contributing
- License
- Acknowledgments
- Disclaimer
These instructions will get you lucid up and running on your openHAB server.
- openHAB version 2.3 or later
- The Experimental Next-Gen Rule Engine add-on must be installed in openHAB 2.
- openHAB should be configured to use a persistence service.
-
Follow the documentation to install JSR223 Jython Scripting unless you already done that. Now, according to the documentation you have already set the
EXTRA_JAVA_OPTS
environment variable in/etc/default/openhab2
to something similar to this example:EXTRA_JAVA_OPTS=-Xbootclasspath/a:/home/pi/jython2.7.0/jython.jar \ -Dpython.home=/home/pi/jython2.7.0 \ -Dpython.path=/etc/openhab2/automation/lib/python
The last line in the example above defines the path where openHAB can find your jython library files. You can choose a different directory for your installation. We prefer using the directory
/etc/openhab2/automation/lib/python
(The JSR223 Jython Scripting documentation uses a different lib directory which is also OK) We will now simply refer to that directory as the LIB-DIR. It's the directory where openHAB will look for your jython library files. -
Download the lucid archive file, extract it in a temporary location.
-
From the extracted zip file, transfer the lucid folder together with all its content (found in the zip file's automation/lib/python folder) into your LIB-DIR.
-
Change the owner, group and file permissions. E.g. cd into the LIB-DIR and run
sudo chown -R openhab:openhab lucid
followed bysudo chmod -R 664 lucid
-
From the extracted zip file, transfer all the the files from the jsr223 (found in the zip file's automation/jsr223 folder) into your
automation/jsr223
directory -
Change the owner, group and file permissions. E.g. cd into your
automation/jsr223
directory and runsudo chown openhab:openhab 000_*.py
followed bysudo chmod 664 000_*.py
-
Create an openHAB item named
ZZZ_Test_Reload_Finished
and put it last in your items file. Make that item persisted "on change". In the example below, persistance "on change" is assigned to the groupG_PersistOnChange
String ZZZ_Test_Reload_Finished (G_PersistOnChange) // Used for checking if reloading
You'd probably want to configure logging for lucid in the config file for logging. The config file for logging is org.ops4j.pax.logging.cfg located in the userdata/etc folder (manual setup) or in /var/lib/openhab2/etc (apt/deb-based setup). See the documentation. In the OSGi appender
section, after line log4j2.logger.org_eclipse_smarthome_automation.name = org.eclipse.smarthome.automation
, add
log4j2.logger.lucid.level = DEBUG
log4j2.logger.lucid.name = lucid
Put the helloWorld.py file from the examples in your automation/jsr223
directory and watch the openHAB log file carefully. It should output "Hello world from lucid!" once every minute. Delete the helloWorld.py
file when you are done.
For some functionality, like the ability to send autoremote messages for example, there is some configuration to do. In LIB-DIR/lucid, rename the file example_config.py to config.py and edit the file to suit your needs. It should be quite self explanatory what it's all about. The configuration file can also be used to store custom config entries for all your jython scripts. The configuration entries are available in the lucid rules that you define.
if (self.config.somerandomdata['anumber'] == 0):
# Do something
Some script packages based on lucid may assume that you have defined a configuration file so it's recommended that you create one now.
You are now ready to make your own scripts using lucid. Have a look at the examples or continue at Writing scripts.
In order for your jython scripts to work with lucid, they need to
- Import mandatory libraries
- Define one or more rule classes with functions that return what triggers you wish to use and an execute function which is where you define what should be executed when the triggers fire.
- Add the rule class to the automation manager.
For example:
from lucid.rules import rule, addRule
from lucid.triggers import ItemStateChangeTrigger
@rule
class ExampleRule(object):
def getEventTriggers(self):
return [
ItemStateChangeTrigger('My_TestSwitch_1'),
]
def execute(self, modules, inputs):
self.log.info('Something has happened')
addRule(ExampleRule())
Some useful text will soon be found here.
Before a rule scripts does anything, it has to be triggered. What kind of triggers that are available is very well documented for the rules DSL (using Xtend programming language) that you see here. (We have copied some text from that documentation and made some changes to it to suit lucid)
There are different categories of rule triggers:
- Item(-Event)-based triggers: They react on events on the openHAB event bus, i.e. commands and status updates for items
- Time-based triggers: They react at special times, e.g. at midnight, every hour, etc.
- System-based triggers: They react on certain system statuses.
- Thing-based triggers: They react on thing status, i.e. change from ONLINE to OFFLINE.
- Channel-based triggers: They react on channels provided by some add-ons.
Here are the details for each category:
You can listen to commands for a specific item, on status updates or on status changes (an update might leave the status unchanged). You can decide whether you want to catch only a specific command/status or any. Here is the syntax for all these cases (parts in square brackets are optional):
ItemCommandTrigger('<item>', ['<command>']), # Item received command
ItemStateUpdateTrigger('<item>', ['<state>']), # Item received update
ItemStateChangeTrigger('<item>', ['<state>']), # Item changed
A simplistic explanation of the differences between command and update can be found in the article about openHAB core actions.
lucid supports cron expressions.
CronTrigger(EVERY_MINUTE), # Using one of the predefined cron expression strings
CronTrigger('3 11 09 * * ?'), # Runs at 09:11:03 every day
CronTrigger(EVERY_15_MINUTES), # Using one of the predefined cron expression strings
A cron expression takes the form of six or optionally seven fields:
- Seconds
- Minutes
- Hours
- Day-of-Month
- Month
- Day-of-Week
- Year (optional field) For more information see the Quartz documentation.
You may also use CronMaker or the generator at FreeFormatter.com to generate cron expressions.
For your convenience there is a set of predefined cron expression constants available within the scope of the getEventTriggers function:
EVERY_10_SECONDS
EVERY_15_SECONDS
EVERY_30_SECONDS
EVERY_MINUTE
EVERY_OTHER_MINUTE
EVERY_5_MINUTES
EVERY_10_MINUTES
EVERY_15_MINUTES
EVERY_30_MINUTES
EVERY_HOUR
EVERY_6_HOURS
EVERY_DAY_AROUND_NOON
Note that this will trigger at a every day "around noon" between 11:03 AM and 12:57 AM.
NOTE!! To avoid the "top of the minute problem" we space out our cronjobs (only those that are using predefined cron expressions) not to occur exactly on the minute or at the top of the hour. That will help your own server as well as shared resources that you'll be using to spread out the work more evenly. Each of the above predefined cron expressions will be randomized at openHAB reload. The EVERY_HOUR
expression might for example be randomized to occur at second :19, minute 32 every hour It will still run once an hour but using the expressons above you can not be certain exactly when. If you for some reason would like to run a cron expression hourly, triggering at minute 0 and second 0 you should not use the predfined cron expressions.
You don't need to specifically import these cron expression string constants. Just use them like:
CronTrigger(EVERY_HOUR), # Runs every hour but not on the minute 00
CronTrigger(EVERY_DAY_AROUND_NOON), # Runs every day around noon +- 1 hour
A single system-based trigger is provided by lucid.
-
System started. System started is triggered upon openHAB startup, after the rule file containing the System started trigger is modified, or after item(s) related to that rule file are modified in a .items file.
-
System shuts down isn't yet implemented.
Example:
StartupTrigger(),
lucid doesn't currently support thing based triggers.
Some add-ons provide trigger channels. Compared with other types of channels, a trigger channel provides information about discrete events, but does not provide continuous state information.
Your rules can take actions based upon trigger events generated by these trigger channels. You can decide whether you want to catch only a specific or any trigger the channel provides. Here is the syntax for these cases (parts in square brackets are optional):
ChannelEventTrigger('<triggerChannel>','<triggerEvent>')
triggerChannel is the identifier for a specific channel.
When a binding provides such channels, you can find the needed information in the corresponding binding documentation. There is no generic list of possible values for triggerEvent, The triggerEvent(s) available depend upon the specific implementation details of the binding.
Example:
ChannelEventTrigger('astro:sun:local:rise#event','START'),
ChannelEventTrigger('astro:sun:local:set#event','START'),
ChannelEventTrigger('astro:sun:local:civilDusk#event','START'),
ChannelEventTrigger('astro:sun:local:civilDusk#event','END'),
Some useful text will soon be found here.
To restart the Jython binding and reload all the Jython libs & scripts, Access the console and isse the following command:
bundle:restart org.eclipse.smarthome.automation.module.script.rulesupport
To make sure that the Jython rule binding binding is loaded as after all the items are initialized, (This has to be done after every OpenHAB2 update) Access the console and isse the following command:
bundle:start-level org.eclipse.smarthome.automation.module.script.rulesupport 90
There are several ways to contribute to this project.
We'd need some help from native english speakers to correct and improve this documentation regarding the language.
OH-Jython-Scripters now has a Slack channel! It will help us to make sense of our work, and drive our efforts in Jython scripting forward. So if you are just curious, got questions, need support or just like to hang around, don't hesitate, join openHAB Jython Scripting on Slack <--- Click link!
This project is licensed under the Eclipse Public License 1.0
- Steve Bate made openHab2-jython, the great work from which lucid is derived from.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.