Merge commit '1a15b6c7fc30e9b3860a70b0a7dc19185b880d27' into HEAD
commit
3c6bee1885
|
@ -25,3 +25,7 @@ MD033: false
|
|||
# Code block style
|
||||
MD046:
|
||||
style: fenced
|
||||
|
||||
#Emphasiszis in asterisk
|
||||
MD049:
|
||||
style: underscore
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
# Reference workflow file in ".github folder"
|
||||
# to allow local development and workflow with one configuration
|
||||
|
||||
extends: "./.github/.markdownlint.yaml"
|
||||
|
||||
# Any configuration should be done in the workflow file
|
16
README.md
16
README.md
|
@ -8,9 +8,9 @@ The result is available at [https://openhab.org/docs/](https://www.openhab.org/d
|
|||
|
||||
## How it works
|
||||
|
||||
In this repo you can find and improve all *general* documentation contents.
|
||||
In this repo you can find and improve all _general_ documentation contents.
|
||||
In fact that is all you can see in the `main` branch.
|
||||
There are also other *read-only* branches, which hold external content like the *add-ons* and *concepts* documentation.
|
||||
There are also other _read-only_ branches, which hold external content like the _add-ons_ and _concepts_ documentation.
|
||||
We will read about them later.
|
||||
|
||||
### So I can't improve an add-on article here?
|
||||
|
@ -44,7 +44,7 @@ You can read a bit more below about our external resources and how we get them.
|
|||
|
||||
### Automatically Generated Parts
|
||||
|
||||
Those parts include __all__ add-on documentation files, no matter if they are from the `openhab-core` repo, the `openhab-addons` repo or any special binding repo like *habmin*, *zwave* or the *alexa skill*.
|
||||
Those parts include __all__ add-on documentation files, no matter if they are from the `openhab-core` repo, the `openhab-addons` repo or any special binding repo like _habmin_, _zwave_ or the _alexa skill_.
|
||||
|
||||
We are keeping all those files at their original location, because it simply doesn't make sense to keep them here.
|
||||
Imagine you want to do an improvement of the zwave binding and have to update the readme file in a completely different place.
|
||||
|
@ -60,8 +60,8 @@ The process below is subject to changes until the openHAB 3.x website become the
|
|||
### How the documentation build works
|
||||
|
||||
We have set up our [build server](https://ci.openhab.org/view/Documentation%20(3.x)/) to do the magic automatically.
|
||||
There are several triggers (mostly time based), which will then *gather the external contents* and move them to our [final](https://github.com/openhab/openhab-docs/tree/final) branch.
|
||||
You can find this migrated external content in the *final* branch under:
|
||||
There are several triggers (mostly time based), which will then _gather the external contents_ and move them to our [final](https://github.com/openhab/openhab-docs/tree/final) branch.
|
||||
You can find this migrated external content in the _final_ branch under:
|
||||
|
||||
- `_addons_*`
|
||||
- `concepts`
|
||||
|
@ -71,14 +71,14 @@ The external content is updated by the following toolchain:
|
|||
|
||||
- `update-external-resources.sh` → `pom.xml` → `process_addons.groovy`
|
||||
|
||||
Everything that gets updated in the *master* branch will be also merged over to the *final* branch automatically.
|
||||
Afterwards we will redeploy the website with the latest content from the *final* branch at regular intervals.
|
||||
Everything that gets updated in the _master_ branch will be also merged over to the _final_ branch automatically.
|
||||
Afterwards we will redeploy the website with the latest content from the _final_ branch at regular intervals.
|
||||
|
||||
#### Build triggers investigated
|
||||
|
||||
There are two triggers available currently.
|
||||
The `merge docs` job is triggerd after something has been added to the documentation through this repository.
|
||||
The `gather external docs` job is started with a **succesful** build of the openhab-distribution.
|
||||
The `gather external docs` job is started with a __succesful__ build of the openhab-distribution.
|
||||
A succesful disribution build will include all of the latest changes that have been made to external sources like addons.
|
||||
So when a distribution build is succesful, we will trigger the gathering of all external sources.
|
||||
|
||||
|
|
|
@ -177,7 +177,7 @@ The Timer object supports the following methods:
|
|||
|
||||
- `cancel`: prevents the scheduled timer from executing. Most of the time `cancel` is used used in conjunction with setting the timer handler to `null` as a convenient indicator that some previously defined timer is now finished with. However setting the handler to `null` does not interact with the timer itself.
|
||||
- `isActive`: returns `true` if the timer will be executed as scheduled, i.e. it has not been cancelled or completed.
|
||||
- `isCancelled`: returns `true` if the timer has been cancelled *before* it completed.
|
||||
- `isCancelled`: returns `true` if the timer has been cancelled _before_ it completed.
|
||||
- `isRunning`: returns `true` if the code is currently executing (i.e. the timer activated the code but it is not done running).
|
||||
- `hasTerminated`: returns `true` if the timer has been cancelled or the code has run and completed.
|
||||
- `reschedule(AbstractInstant instant)`: reschedules the timer to execute at the new time. If the Timer has terminated this method does nothing.
|
||||
|
@ -227,7 +227,7 @@ Notification actions may be placed in Rules to send alerts to mobile devices reg
|
|||
Three different actions are available:
|
||||
|
||||
- `sendNotification(emailAddress, message)`: Sends a notification to a specific cloud instance user
|
||||
- `sendBroadcastNotification(message)`: Sends a notification to *all* devices of *all* users
|
||||
- `sendBroadcastNotification(message)`: Sends a notification to _all_ devices of _all_ users
|
||||
- `sendLogNotification(message)`: Sends a log notification to the `notifications` list at your openHAB Cloud instance. Notifications are NOT sent to any registered devices
|
||||
|
||||
For each of the three actions, there's another variant accepting an icon name and a severity:
|
||||
|
|
|
@ -7,7 +7,7 @@ title: System Integrations
|
|||
|
||||
openHAB supports services that enable integration with various technologies that don't fall into other add-on categories.
|
||||
|
||||
Most of the systems mentioned below are integrated via a *Misc* add-on, installed e.g. through UI.
|
||||
Most of the systems mentioned below are integrated via a _Misc_ add-on, installed e.g. through UI.
|
||||
Detailed instructions and requirements may be found in the corresponding documentation pages.
|
||||
|
||||
<!-- selection not needed for now table id="ios-select" class="striped">
|
||||
|
|
|
@ -68,7 +68,7 @@ where
|
|||
|
||||
These bundle names are used in many places in openHAB, such as in various configuration files.
|
||||
Logging also makes extensive use of this **package namespace**.
|
||||
You can see these names listed as the *Symbolic names* of bundles by using the ```-s``` option of _bundle:list_:
|
||||
You can see these names listed as the _Symbolic names_ of bundles by using the ```-s``` option of _bundle:list_:
|
||||
|
||||
```text
|
||||
openhab> bundle:list -s
|
||||
|
|
|
@ -94,7 +94,7 @@ openhab> help bundle:stop
|
|||
|
||||
The console also supports auto-completion during input.
|
||||
Auto-completion proposes possible commands based on the current input and is triggered by a <TAB> press on your keyboard.
|
||||
So for example entering "*bund*" and pressing the <TAB> key will first extend to the only viable candidate "bundle", a subsequent <TAB> press will result in:
|
||||
So for example entering "_bund_" and pressing the <TAB> key will first extend to the only viable candidate "bundle", a subsequent <TAB> press will result in:
|
||||
|
||||
```text
|
||||
openhab> bundle
|
||||
|
|
|
@ -8,31 +8,31 @@ title: Audio & Voice
|
|||
Audio and voice features are an important aspect of any smart home solution as it is a very natural way to interact with the user.
|
||||
|
||||
openHAB has a very modular architecture that enables many different use cases.
|
||||
At its core, there is the notion of an *audio stream*.
|
||||
Audio streams are provided by *audio sources* and consumed by *audio sinks*.
|
||||
At its core, there is the notion of an _audio stream_.
|
||||
Audio streams are provided by _audio sources_ and consumed by _audio sinks_.
|
||||
|
||||

|
||||
|
||||
- *Audio Streams* are essentially byte streams with a given *audio format*.
|
||||
- _Audio Streams_ are essentially byte streams with a given _audio format_.
|
||||
They do not need to be limited in size, i.e. it is allowed to have continuous streams, e.g. the input from a microphone or from an Internet radio station.
|
||||
- *Audio Formats* define the container (e.g. WAV), encoding, bit rate, sample frequency and depth and the bit order (little or big endian).
|
||||
- *Audio Sources* are services that are capable of producing audio streams.
|
||||
- _Audio Formats_ define the container (e.g. WAV), encoding, bit rate, sample frequency and depth and the bit order (little or big endian).
|
||||
- _Audio Sources_ are services that are capable of producing audio streams.
|
||||
They can support different formats and provide a stream in a requested format upon request.
|
||||
Typical audio source services are microphones. Typically, a continuous stream is expected from them.
|
||||
- *Audio Sinks* are services that accept audio streams of certain formats.
|
||||
- _Audio Sinks_ are services that accept audio streams of certain formats.
|
||||
Typically, these are expected to play the audio stream, i.e. they are some kind of speaker or media device.
|
||||
- *Text-to-Speech* (TTS) services are similar to audio sources with respect to the ability to create audio streams.
|
||||
- _Text-to-Speech_ (TTS) services are similar to audio sources with respect to the ability to create audio streams.
|
||||
The difference is that they take a string as an input and will synthesize this string to a spoken text using a given voice.
|
||||
TTS services can provide information about the voices that they support and the locale that those voices are associated with.
|
||||
Each voice supports exactly one locale.
|
||||
- *Speech-to-Text* (STT) services are similar to audio sinks, but they do not simply play back the stream, but convert it to a plain string.
|
||||
- _Speech-to-Text_ (STT) services are similar to audio sinks, but they do not simply play back the stream, but convert it to a plain string.
|
||||
They provide information about supported formats and locales.
|
||||
|
||||
As plain text from an STT service is often not very useful, there is additionally the concept of a *human language interpreter*:
|
||||
As plain text from an STT service is often not very useful, there is additionally the concept of a _human language interpreter_:
|
||||
|
||||

|
||||
|
||||
A *Human Language Interpreter* takes a string as an input.
|
||||
A _Human Language Interpreter_ takes a string as an input.
|
||||
It then derives actions from it (like sending commands to devices) and/or replies with a string, which opens the possibility to realize conversations.
|
||||
As such an interpreter is not directly linked to audio streams, but operates on strings only, this can be the basis for any kind of assistant, e.g. for chat bots using the console, XMPP, Twitter or other messaging services.
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ openhab-binding-network | 3.0.0.M5 | | Uninst
|
|||
...
|
||||
```
|
||||
|
||||
According to the [naming convention for bundles](/docs/administration/bundles.html#naming-convention-for-bundles) the *id* for the shown example is *network*.
|
||||
According to the [naming convention for bundles](/docs/administration/bundles.html#naming-convention-for-bundles) the _id_ for the shown example is _network_.
|
||||
|
||||
Another way to find the correct `id` is to look at the URL of the add-on documentation page.
|
||||
For example the url for the [Network Binding documentation](/addons/bindings/network/) is
|
||||
|
@ -48,7 +48,7 @@ https://www.openhab.org/addons/bindings/network/
|
|||
|
||||
In this case, the `id` would be "network".
|
||||
|
||||
With this information we can now edit the *addons.cfg* file in the `$OPENHAB_CONF/services` folder on the machine you are running openHAB on.
|
||||
With this information we can now edit the _addons.cfg_ file in the `$OPENHAB_CONF/services` folder on the machine you are running openHAB on.
|
||||
The path depends on your installation.
|
||||
You can find out the correct locations on the corresponding documentation pages, e.g. [Linux](/docs/installation/linux.html#file-locations) or [Windows](/docs/installation/windows.html#file-locations).
|
||||
|
||||
|
@ -62,7 +62,7 @@ transformation = jsonpath
|
|||
persistence = influxdb
|
||||
```
|
||||
|
||||
To install the network Binding like we want in this example, we just need to add the id *network* to the Binding section.
|
||||
To install the network Binding like we want in this example, we just need to add the id _network_ to the Binding section.
|
||||
|
||||
```text
|
||||
binding = astro,network
|
||||
|
|
|
@ -24,12 +24,12 @@ Therefore openHAB also provides a graphical way of writing rules which allows to
|
|||
The basic idea behind the visual paradigm and representation within openHAB is based on the [Google Blockly Support](https://developers.google.com/blockly) which has been integrated and which provides the basic blocks for programming like the ones on the left and the right side of the below images
|
||||
|
||||
{: #blockly-toolbox}
|
||||
*Blockly toolbox*
|
||||
_Blockly toolbox_
|
||||
|
||||

|
||||
|
||||
All of these provide general functionality that is not specific to openHAB itself. If you want to learn more about how to use them, search for the many blockly tutorials that are available.
|
||||
However, to leverage the full capabilities more than *50 specific blocks* have been provided that are tailored for easy access of openHAB's capabilities.
|
||||
However, to leverage the full capabilities more than _50 specific blocks_ have been provided that are tailored for easy access of openHAB's capabilities.
|
||||
|
||||
This section provides a detailed description of the specific blocks and provides examples on how to use them. Note that some of the blocks (like voice, streaming or notifications) need some special setup within openHAB - in these case links to the respective documentation is provided.
|
||||
Also see this  [Intro](https://youtu.be/EdllUlJ7p6k?t=295) Quick Intro Blockly Rules
|
||||
|
@ -45,7 +45,7 @@ There is also a help-button available in each section that links to the document
|
|||
|
||||

|
||||
|
||||
Please read this information first before asking questions in the forum. *In case you ask for help please always post the respective code that is being generated.*
|
||||
Please read this information first before asking questions in the forum. _In case you ask for help please always post the respective code that is being generated._
|
||||
|
||||
Also there is a good intro about that topic can be viewed at  [Various Help Documentation available in openHAB Blocky](https://youtu.be/EdllUlJ7p6k?t=1589)
|
||||
|
||||
|
@ -111,7 +111,7 @@ Also view  [Overview of the
|
|||
|
||||
### Items and Things
|
||||
|
||||
*Items* and *Things* are the [major entities of openHAB](https://www.openhab.org/docs/concepts/) to control and monitor the home.
|
||||
_Items_ and _Things_ are the [major entities of openHAB](https://www.openhab.org/docs/concepts/) to control and monitor the home.
|
||||
|
||||
[
|
||||
](rules-blockly-items-things.html)
|
||||
|
@ -131,7 +131,7 @@ See [Timers and Delays](rules-blockly-timers-and-delays.html) section.
|
|||
### Date Handling
|
||||
|
||||
Date blocks are used as input parameters for other blocks.
|
||||
Some of these blocks are used by ephemeris blocks, whilst others are used in the persistence section. Therefore blocks are *typed* to assure correct connection to other blocks.
|
||||
Some of these blocks are used by ephemeris blocks, whilst others are used in the persistence section. Therefore blocks are _typed_ to assure correct connection to other blocks.
|
||||
|
||||
[
|
||||
](rules-blockly-date-handling.html) [
|
||||
|
@ -151,7 +151,7 @@ See [Ephemeris](rules-blockly-ephemeris.html) section.
|
|||
|
||||
### Voice and Multimedia
|
||||
|
||||
This section deals with *playing or streaming audio* to an audio sink e.g a speaker or *saying a text* via using any Text-to-Speech API (e.g. Google's API)
|
||||
This section deals with _playing or streaming audio_ to an audio sink e.g a speaker or _saying a text_ via using any Text-to-Speech API (e.g. Google's API)
|
||||
|
||||
[
|
||||
](rules-blockly-voice-and-multimedia.html)
|
||||
|
@ -179,7 +179,7 @@ See [Persistence](rules-blockly-persistence.html) section.
|
|||
|
||||
### Value Storage
|
||||
|
||||
These blocks enable storing information *for a rule* that is kept after the rule has run, so it can be reused when the rule is run again later in stateful way.
|
||||
These blocks enable storing information _for a rule_ that is kept after the rule has run, so it can be reused when the rule is run again later in stateful way.
|
||||
|
||||
[
|
||||
](rules-blockly-value-storage.html)
|
||||
|
|
|
@ -25,17 +25,17 @@ Please read them carefully before asking questions in the forum.
|
|||
## **OpenHAB Configuration Files**
|
||||
|
||||
Some openHAB blocks rely on particular configuration files found in the openHAB configuration folder.
|
||||
This folder is referred to as $OPENHAB_CONF in this page, and the location of this folder for your setup can be found via the UI: *Help & About* -> *Technical Information* -> *Configuration folder*.
|
||||
This folder is referred to as $OPENHAB_CONF in this page, and the location of this folder for your setup can be found via the UI: _Help & About_ -> _Technical Information_ -> _Configuration folder_.
|
||||
|
||||
- via mounting the files shares from the server to your client-PC.
|
||||
In the main UI as an admin you can go to *Help & About* and will have the different folder locations under *Technical information*.
|
||||
In the main UI as an admin you can go to _Help & About_ and will have the different folder locations under _Technical information_.
|
||||
- the exact configuration of the shares can be found on your server at [/etc/samba/smb.conf](https://github.com/openhab/openhabian/blob/main/includes/smb.conf).
|
||||
- Use the share *openHAB*-conf when mounting it from Windows or MacOS
|
||||
- Use the share _openHAB_-conf when mounting it from Windows or MacOS
|
||||
|
||||
**Link the openHAB share in Windows**
|
||||
|
||||
- Find you openHAB-Server via the network share functionality
|
||||
- User the share *openHAB*-conf to assign it to a network drive
|
||||
- User the share _openHAB_-conf to assign it to a network drive
|
||||
|
||||
**Link the openHAB share in macOS**
|
||||
|
||||
|
@ -49,7 +49,7 @@ In the main UI as an admin you can go to *Help & About* and will have the differ
|
|||
|
||||
**Finding it on Linux**
|
||||
|
||||
- Access the folder directly on the openHAB server at */etc/openhab*
|
||||
- Access the folder directly on the openHAB server at _/etc/openhab_
|
||||
|
||||
All methods reveal the following folders
|
||||
|
||||
|
@ -132,7 +132,7 @@ Pinching on a tablet or a touch bar also allows convenient zooming of the worksp
|
|||
|
||||
During development the log-block is lot very often which writes information into the log files.
|
||||
|
||||
- To be able to conveniently view your log files it is recommended to setup *frontail* which can be achieved easily via [openhabian-config](https://www.openhab.org/docs/installation/openhabian.html#optional-components)
|
||||
- To be able to conveniently view your log files it is recommended to setup _frontail_ which can be achieved easily via [openhabian-config](https://www.openhab.org/docs/installation/openhabian.html#optional-components)
|
||||
- Start `openhabian-config` on your server and choose option 20 and then option 21
|
||||
- After installation you can view your logs under [openhabian-config](http://myopenhab-server:9001) (adapt the server name)
|
||||
- **see [how to log](https://www.openhab.org/docs/administration/logging.html)**
|
||||
|
|
|
@ -26,7 +26,7 @@ With 3.3.0M6 many blocks were introduced to allow complex tasks with dates
|
|||
|
||||

|
||||
|
||||
Note: There is *no need* for a special block to set a datetime of an openHAB item.
|
||||
Note: There is _no need_ for a special block to set a datetime of an openHAB item.
|
||||
This can be directly done via the ["send command" / "post command" block](rules-blockly-items-things.html#send-command)
|
||||
|
||||
## Date Handling Blocks
|
||||
|
@ -45,17 +45,17 @@ This button serves as a link to this documention page
|
|||
|
||||

|
||||
|
||||
Type: *ZonedDateTime*
|
||||
Type: _ZonedDateTime_
|
||||
|
||||
Obtains the current datetime from the system clock in the default timezone as *ZonedDateTime*
|
||||
Obtains the current datetime from the system clock in the default timezone as _ZonedDateTime_
|
||||
|
||||
### Get Datetime now with offset
|
||||
|
||||

|
||||
|
||||
Type: *ZonedDateTime*
|
||||
Type: _ZonedDateTime_
|
||||
|
||||
Obtains the current datetime as *ZonedDateTime* with an offset relative to the current date *and* time.
|
||||
Obtains the current datetime as _ZonedDateTime_ with an offset relative to the current date _and_ time.
|
||||
|
||||
The options for the time period base are
|
||||
|
||||
|
@ -70,9 +70,9 @@ The options for the time period base are
|
|||
|
||||

|
||||
|
||||
Type: *ZonedDateTime*
|
||||
Type: _ZonedDateTime_
|
||||
|
||||
Returns a date as *ZonedDateTime*.
|
||||
Returns a date as _ZonedDateTime_.
|
||||
The date can be selected from a date picker.
|
||||
The time is set to `00:00:00`.
|
||||
|
||||
|
@ -80,9 +80,9 @@ The time is set to `00:00:00`.
|
|||
|
||||

|
||||
|
||||
Type: *ZonedDateTime*
|
||||
Type: _ZonedDateTime_
|
||||
|
||||
This block will return the date as *ZonedDateTime* based on the given String.
|
||||
This block will return the date as _ZonedDateTime_ based on the given String.
|
||||
The String may be one of the following formats (since 3.3) the following formats are supported)
|
||||
|
||||
- yyyy-MM-dd
|
||||
|
@ -106,7 +106,7 @@ More about that topic can be viewed at 
|
||||
|
||||
Type: *ZonedDateTime*
|
||||
Type: _ZonedDateTime_
|
||||
|
||||
Creates a ZonedDateTime by providing all necessary six values
|
||||
|
||||
|
@ -127,7 +127,7 @@ More about that topic can be viewed at 
|
||||
|
||||
Type: *ZonedDateTime*
|
||||
Type: _ZonedDateTime_
|
||||
|
||||
This block allows to create a new ZonedDateTime based on a given ZonedDateTime and then either
|
||||
|
||||
|
@ -149,7 +149,7 @@ The following short video explains how the block can be used
|
|||

|
||||
|
||||
- first drag the main copyOf-Block to the workspace
|
||||
- choose the datetime you want to base your *new* datetime on and drag it into the position (in the above video the now block is used)
|
||||
- choose the datetime you want to base your _new_ datetime on and drag it into the position (in the above video the now block is used)
|
||||
- select if you want to set (overwrite), add or subtract values via the dropdown
|
||||
- open the settings icon and drag as many "temporal units" into the block as you want to modify later, which will create the "holes" into which you can apply the temporal blocks
|
||||
- now drag one of the temporal blocks (see description below) in each of these blocks.
|
||||
|
@ -209,7 +209,7 @@ since 3.3
|
|||
|
||||

|
||||
|
||||
Type: *ZonedDateTime*
|
||||
Type: _ZonedDateTime_
|
||||
|
||||
This is a convenience block that retrieves the state of an item (at best of item type datetime) which is then automatically converted to a ZonedDateTime, so it can be easily used as shown in the following example:
|
||||
|
||||
|
@ -221,9 +221,9 @@ More about that topic can be viewed at 
|
||||
|
||||
Type: *String*
|
||||
Type: _String_
|
||||
|
||||
Returns the String representation of a given *ZonedDateTime*-block, with or without the time.
|
||||
Returns the String representation of a given _ZonedDateTime_-block, with or without the time.
|
||||
|
||||
since 3.3: also returns the same datetime format that is used by openHAB itself
|
||||
|
||||
|
@ -252,7 +252,7 @@ An introduction to that topic can be viewed at 
|
||||
|
||||
Type: *Number*
|
||||
Type: _Number_
|
||||
|
||||
Returns the selected part of the datetime as a number.
|
||||
|
||||
|
@ -288,7 +288,7 @@ since 3.3
|
|||
Calculates the amount of time between two datetimes.
|
||||
The result will be negative if the second object is before the first one.
|
||||
|
||||
Type: *Number*
|
||||
Type: _Number_
|
||||
|
||||
Returns the difference between the two datetimes.
|
||||
|
||||
|
@ -298,7 +298,7 @@ Returns the difference between the two datetimes.
|
|||
|
||||

|
||||
|
||||
Type: *DayOffset*
|
||||
Type: _DayOffset_
|
||||
|
||||
Ephemeris blocks expect a date formatted as the number of days since today.
|
||||
As a result, this block always returns 0.
|
||||
|
@ -308,7 +308,7 @@ Used for Emphemeris blocks only.
|
|||
|
||||

|
||||
|
||||
Type: *DayOffset*
|
||||
Type: _DayOffset_
|
||||
|
||||
Returns the number of days since today, as configured in the number block.
|
||||
The number can be positive (offset into the future) or negative (offset into the past).
|
||||
|
|
|
@ -14,7 +14,7 @@ The ephemeris category provides blocks with calendar functionality.
|
|||
The blocks can be used to determine what type of day today is, or a number of days before or after today is.
|
||||
For example, a way to determine if today is a weekend, a bank holiday, someone’s birthday, trash day, etc.
|
||||
|
||||
Definition of holidays can be customised through the *ephemeris.cfg* file.
|
||||
Definition of holidays can be customised through the _ephemeris.cfg_ file.
|
||||
See the [Ephemeris configuration page](https://www.openhab.org/docs/configuration/actions.html#configuration) for more information.
|
||||
|
||||
{::options toc_levels="2..4"/}
|
||||
|
@ -34,9 +34,9 @@ More about that topic can be viewed at 
|
||||
|
||||
*Function:* this block checks if the given date is a holiday, weekday or weekend.
|
||||
_Function:_ this block checks if the given date is a holiday, weekday or weekend.
|
||||
|
||||
Type: *boolean* `true` or `false`
|
||||
Type: _boolean_ `true` or `false`
|
||||
|
||||
**Examples**
|
||||
|
||||
|
@ -46,10 +46,10 @@ Type: *boolean* `true` or `false`
|
|||
|
||||

|
||||
|
||||
*Function:* Returns the holiday name for the given date.
|
||||
_Function:_ Returns the holiday name for the given date.
|
||||
Will return `null` if no holiday is found for the date.
|
||||
|
||||
Type: *String*
|
||||
Type: _String_
|
||||
|
||||
### Get the number of days until a specific holiday
|
||||
|
||||
|
@ -60,7 +60,7 @@ Function: Return the number of days until the given holiday name, or `-1` if the
|
|||
Type: number
|
||||
|
||||
Some holidays are already provided by default from openHAB.
|
||||
Additional holidays must be configured in *ephemeris.cfg*.
|
||||
Additional holidays must be configured in _ephemeris.cfg_.
|
||||
|
||||
## Return to Blockly Reference
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ title: Rules Blockly - Items & Things
|
|||
|
||||
## Introduction
|
||||
|
||||
*Items* and *Things* are the [major entities of openHAB](https://www.openhab.org/docs/concepts/) to control and monitor the home.
|
||||
_Items_ and _Things_ are the [major entities of openHAB](https://www.openhab.org/docs/concepts/) to control and monitor the home.
|
||||
These can be accessed via the "Items & Things" section of the [Blockly Toolbox](/docs/configuration/index.html#blockly-toolbox).
|
||||
|
||||
{::options toc_levels="2..4"/}
|
||||
|
@ -26,14 +26,14 @@ These can be accessed via the "Items & Things" section of the [Blockly Toolbox](
|
|||
|
||||
### Item and Thing Blocks
|
||||
|
||||
Most of the time you will want to get and set the state of an *item* - set a switch to ON, or get a temperature.
|
||||
Sometimes you may want to access the *thing* directly.
|
||||
Most of the time you will want to get and set the state of an _item_ - set a switch to ON, or get a temperature.
|
||||
Sometimes you may want to access the _thing_ directly.
|
||||
Both are possible using the item-block and thing-block
|
||||
|
||||
> 
|
||||
|
||||
However, **these blocks are not useful by themselves** - they are always used together with another block.
|
||||
The example below uses the *get state of item* block to retrieve the *MainSwitch* *item* state, before checking if that is equal to ON within a standard comparison block
|
||||
The example below uses the _get state of item_ block to retrieve the _MainSwitch_ _item_ state, before checking if that is equal to ON within a standard comparison block
|
||||
|
||||

|
||||
|
||||
|
@ -50,7 +50,7 @@ Function: Retrieves a specific **Item** or **Group** for use in other item relat
|
|||
- **Tip:** never use this block alone as it only returns the items name which alone does not make sense.
|
||||
Instead use the get-Item-Block below.
|
||||
- Clicking 'MyItem' displays a list of **Items** to pick from
|
||||
- Technically this block returns the *name* of the item as a String.
|
||||
- Technically this block returns the _name_ of the item as a String.
|
||||
- As a result, this block can be used wherever the item name is required as a String.
|
||||
- Learn more about items [here](https://www.openhab.org/docs/configuration/items.html)
|
||||
|
||||
|
@ -61,7 +61,7 @@ Instead use the get-Item-Block below.
|
|||
Function: Gets an **Item** for use in other item related functions
|
||||
|
||||
- Clicking 'MyItem' displays a list of **Items** to pick from.
|
||||
- Technically this block returns an item *object*, to be used to retrieve specific attributes using other blocks (see below).
|
||||
- Technically this block returns an item _object_, to be used to retrieve specific attributes using other blocks (see below).
|
||||
- As this block does not return a String it cannot be directly attached to a log-block, as demonstrated below.
|
||||
- **Tip:** Often you do want to retrieve the state, hence use the "Get State of Item"-block below
|
||||
- The block returns the item itself.
|
||||
|
@ -140,11 +140,11 @@ As a workaround attach the block to a variable first, and use the variable in th
|
|||
|
||||
**Special handling for Arrays**
|
||||
|
||||
The attributes *groups* and *tags* return an Array of entries.
|
||||
The attributes _groups_ and _tags_ return an Array of entries.
|
||||
Therefore
|
||||
|
||||
- they *cannot* be connected to a block that expects a String (e.g. log-block)
|
||||
- they *must* be handled using a for-loop as follows
|
||||
- they _cannot_ be connected to a block that expects a String (e.g. log-block)
|
||||
- they _must_ be handled using a for-loop as follows
|
||||
|
||||

|
||||
|
||||
|
@ -157,7 +157,7 @@ Function: Sends a command or posts an update to an **Item** or **Group**.
|
|||
- value: any state value that is allowed for that item, eg. ON or OFF for a switch.
|
||||
- Clicking 'MyItem' displays a list of **Items** to pick one item from
|
||||
|
||||
For the difference between *send command* and *post update* see ["Manipulating States"](https://www.openhab.org/docs/configuration/rules-dsl.html#manipulating-item-states) and ["Event Bus Actions"](https://www.openhab.org/docs/configuration/actions.html#event-bus-actions).
|
||||
For the difference between _send command_ and _post update_ see ["Manipulating States"](https://www.openhab.org/docs/configuration/rules-dsl.html#manipulating-item-states) and ["Event Bus Actions"](https://www.openhab.org/docs/configuration/actions.html#event-bus-actions).
|
||||
|
||||
More about that topic can be viewed at  [Sending Commands](https://youtu.be/EdllUlJ7p6k?t=1077)
|
||||
|
||||
|
@ -165,15 +165,15 @@ More about that topic can be viewed at 
|
||||
|
||||
**Example 2:**
|
||||
|
||||
- Get the state of *MainSwitch* and
|
||||
- Immediately send it as a command to *F2_Office_Main_Light*
|
||||
- Get the state of _MainSwitch_ and
|
||||
- Immediately send it as a command to _F2_Office_Main_Light_
|
||||
|
||||

|
||||
Ensure that the receiving item can handle the state of the 'sending' item.
|
||||
|
|
|
@ -31,7 +31,7 @@ More about that topic can be viewed at 
|
||||
|
||||
*Function:* Sends an entry to the openHAB log file with a defined severity level.
|
||||
_Function:_ Sends an entry to the openHAB log file with a defined severity level.
|
||||
|
||||
- A [severity level](https://www.openhab.org/docs/administration/logging.html#defining-what-to-log) can be provided via the dropdown list for the log statement
|
||||
|
||||
|
@ -47,7 +47,7 @@ Since 3.3: The block attached to the log-block is not restricted to a string typ
|
|||
|
||||

|
||||
|
||||
*Function:* creates a print statement with the given text in the rule that logs to *stdout*
|
||||
_Function:_ creates a print statement with the given text in the rule that logs to _stdout_
|
||||
|
||||
## Return to Blockly Reference
|
||||
|
||||
|
|
|
@ -34,14 +34,14 @@ More about that topic can be viewed at 
|
||||
|
||||
*Function:* Sends a notification to the openHAB mobile app via openHAB cloud to a specific user signed up under the given email address
|
||||
_Function:_ Sends a notification to the openHAB mobile app via openHAB cloud to a specific user signed up under the given email address
|
||||
|
||||
- **This block does not use the mail binding**, and it is not possible to send a notification to a user who does not have an openHAB cloud account.
|
||||
- Notification will only work if devices have the openHAB mobile app installed (either iOS or Android)
|
||||
|
||||
### Send Notification to All Devices and users
|
||||
|
||||
*Function:* Sends a notification to all devices and all users to the openHAB mobile app.
|
||||
_Function:_ Sends a notification to all devices and all users to the openHAB mobile app.
|
||||
|
||||

|
||||
|
||||
|
@ -57,9 +57,9 @@ Use the [icon names of the openHAB iconset](https://www.openhab.org/docs/configu
|
|||
|
||||

|
||||
|
||||
*Function:* Sends a notification to myopenhab.org only
|
||||
_Function:_ Sends a notification to myopenhab.org only
|
||||
|
||||
- This notification is *only* sent to the openHAB cloud log (for example at <https://myopenhab.org/notifications>), **not the local openHAB log**.
|
||||
- This notification is _only_ sent to the openHAB cloud log (for example at <https://myopenhab.org/notifications>), **not the local openHAB log**.
|
||||
- Notifications are not sent to users' devices.
|
||||
- For the time being neither the log level nor the icon is shown in the log of the cloud
|
||||
- The notification is not logged on the openhab server
|
||||
|
|
|
@ -39,7 +39,7 @@ More about that topic can be viewed at 
|
||||
|
||||
*Function:* computes any of the below functions for the given item since the time provided by *ZonedDateTime*-Block
|
||||
_Function:_ computes any of the below functions for the given item since the time provided by _ZonedDateTime_-Block
|
||||
|
||||
- average: gets the average value of the State of a persisted Item since a certain point in time.
|
||||
This method uses a time-weighted average calculation
|
||||
|
@ -57,14 +57,14 @@ Note: in case no or 0 values are retrieved, make sure that the item in question
|
|||
|
||||

|
||||
|
||||
*Function:* checks if an item was updated or changed since a certain point in time
|
||||
_Function:_ checks if an item was updated or changed since a certain point in time
|
||||
Type: boolean `true` or `false`
|
||||
|
||||
### Provide last updated date of an Item
|
||||
|
||||

|
||||
|
||||
*Function:* Provides the last updated date (including time) of an Item
|
||||
_Function:_ Provides the last updated date (including time) of an Item
|
||||
Type: ZonedDateTime
|
||||
|
||||
## Return to Blockly Reference
|
||||
|
|
|
@ -18,7 +18,7 @@ This section contains several possibilities
|
|||
|
||||
**A note about Rules and Scripts**
|
||||
|
||||
A Script *is* a Rule too. It’s just a special type of rule that only has a single script action and a “Script” tag.
|
||||
A Script _is_ a Rule too. It’s just a special type of rule that only has a single script action and a “Script” tag.
|
||||
|
||||
{::options toc_levels="2..4"/}
|
||||
|
||||
|
@ -39,7 +39,7 @@ See also the short video part about 
|
||||
|
||||
*Function:* Calls a script file with the given name which must be located in the *$OPENHAB_CONF/scripts/* folder.
|
||||
_Function:_ Calls a script file with the given name which must be located in the _$OPENHAB_CONF/scripts/_ folder.
|
||||
|
||||
- No parameters can be provided
|
||||
|
||||
|
@ -49,15 +49,15 @@ See [openHAB Call-Script](https://www.openhab.org/docs/configuration/actions.htm
|
|||
|
||||

|
||||
|
||||
*Function:* calls another *rule* or *script* that was created via the openHAB UI.
|
||||
_Function:_ calls another _rule_ or _script_ that was created via the openHAB UI.
|
||||
|
||||
The *ruleUID* can be found in the list of rules or scripts in the second line of the list (like here *helloBlockly* or *helloWorld*)
|
||||
The _ruleUID_ can be found in the list of rules or scripts in the second line of the list (like here _helloBlockly_ or _helloWorld_)
|
||||

|
||||
|
||||
Parameters are optional:
|
||||
|
||||
- If not providing parameters leave the *with context* section as is.
|
||||
- If providing parameters you **must** replace the *create empty dictionary* block with [the *dictionary* block from the Lists section](https://community.openhab.org/t/blockly-reference/128785#lists-76), modifying the number of key/value pairs to suit.
|
||||
- If not providing parameters leave the _with context_ section as is.
|
||||
- If providing parameters you **must** replace the _create empty dictionary_ block with [the _dictionary_ block from the Lists section](https://community.openhab.org/t/blockly-reference/128785#lists-76), modifying the number of key/value pairs to suit.
|
||||
|
||||
Notes:
|
||||
|
||||
|
@ -74,7 +74,7 @@ Function: Retrieve context attributes passed by a calling rule/script (see above
|
|||
|
||||
This retrieves the value for the key "myKey1" that was passed by the calling rule.
|
||||
|
||||
*Example*
|
||||
_Example_
|
||||
|
||||

|
||||
|
||||
|
@ -82,7 +82,7 @@ This retrieves the value for the key "myKey1" that was passed by the calling rul
|
|||
|
||||

|
||||
|
||||
*Function:* Retrieve event context related information of the rule
|
||||
_Function:_ Retrieve event context related information of the rule
|
||||
|
||||
A rule carries contextual information when triggered - this block can retrieve that information.
|
||||
|
||||
|
@ -136,7 +136,7 @@ $.device.status.temperature
|
|||
|
||||
### Example 3: Map transformation
|
||||
|
||||
This example applies a map transformation from the map file nanoleaf.map in *$OPENHAB-CONF/transform/*
|
||||
This example applies a map transformation from the map file nanoleaf.map in _$OPENHAB-CONF/transform/_
|
||||
|
||||

|
||||
|
||||
|
@ -162,7 +162,7 @@ Hue/Saturation
|
|||
|
||||

|
||||
|
||||
*Function:* execute arbitrary ECMAScript content
|
||||
_Function:_ execute arbitrary ECMAScript content
|
||||
|
||||
Provides the possibility to inject any ECMAScript at a given position.
|
||||
This should be used in cases when Blockly does not provide the desired functionality.
|
||||
|
|
|
@ -38,7 +38,7 @@ CRLF stands for carriage-return / line-feed which is a technical term for adding
|
|||
|
||||

|
||||
|
||||
*Function:* return a newline character to be added to a string.
|
||||
_Function:_ return a newline character to be added to a string.
|
||||
|
||||
**Example:**
|
||||
|
||||
|
@ -62,25 +62,25 @@ See the special hsb-conversion block below.
|
|||
|
||||

|
||||
|
||||
*Function:* Lets the user pick from a (limited) set of colors and returns a the hexadecimal number (in the above case the value = #33cc00.
|
||||
_Function:_ Lets the user pick from a (limited) set of colors and returns a the hexadecimal number (in the above case the value = #33cc00.
|
||||
|
||||
### Random Color
|
||||
|
||||

|
||||
|
||||
*Function:* Returns a random color as a hexcode
|
||||
_Function:_ Returns a random color as a hexcode
|
||||
|
||||
### Create RGB color
|
||||
|
||||

|
||||
|
||||
*Function:* Returns a color by mixing the given values in a range from 0 - 255 for reg, green and blue as a hexcode
|
||||
_Function:_ Returns a color by mixing the given values in a range from 0 - 255 for reg, green and blue as a hexcode
|
||||
|
||||
### Blend two colors
|
||||
|
||||

|
||||
|
||||
*Function:* Blends two colors chosen via a color picker into one color by the given ratio.
|
||||
_Function:_ Blends two colors chosen via a color picker into one color by the given ratio.
|
||||
|
||||
Tip: this could be used for example with a loop that changes the ratio from 0 to 1 to blend the first color into a second
|
||||
|
||||
|
@ -91,14 +91,14 @@ Tip: this could be used for example with a loop that changes the ratio from 0 to
|
|||
HSB stands for hue-saturation-brightness which is a different way of describing a color.
|
||||
An RGB color can therefore be converted equally into an HSB-color.
|
||||
|
||||
*Function:* This a special openHAB block that converts a hexadecimal color code from one of the above blocks into a String that is required when sending a color command to any item that accepts a color.
|
||||
_Function:_ This a special openHAB block that converts a hexadecimal color code from one of the above blocks into a String that is required when sending a color command to any item that accepts a color.
|
||||
|
||||
- use that block and connect one of the above blocks into that one to be able to retrieve the HSB value of that block.
|
||||
|
||||
HSB stands for hue-saturation-brightness which is a different way of describing a color.
|
||||
An RGB color can therefore be converted equally into an HSB-color.
|
||||
|
||||
*Function:* This a special openHAB block that converts a hexadecimal color code from one of the above blocks into a String that is required when sending a color command to any item that accepts a color.
|
||||
_Function:_ This a special openHAB block that converts a hexadecimal color code from one of the above blocks into a String that is required when sending a color command to any item that accepts a color.
|
||||
|
||||
- use that block and connect one of the above blocks into that one to be able to retrieve the HSB value of that block.
|
||||
|
||||
|
@ -128,7 +128,7 @@ Example:
|
|||
|
||||

|
||||
|
||||
*Function:* Retrieves the value of the key in the given directory
|
||||
_Function:_ Retrieves the value of the key in the given directory
|
||||
|
||||
Example:
|
||||
|
||||
|
|
|
@ -27,17 +27,17 @@ More about that topic can be viewed at 
|
||||
|
||||
*Function:* Suspends execution of the rule for a given period of time
|
||||
_Function:_ Suspends execution of the rule for a given period of time
|
||||
|
||||
- unit of time (ms) is milliseconds (1000 ms = 1 second)
|
||||
|
||||
*Example*
|
||||
_Example_
|
||||
|
||||
The following simple example uses a loop to implement a blinking light with a 1 second delay, looping three times:
|
||||
|
||||
|
@ -45,16 +45,16 @@ The following simple example uses a loop to implement a blinking light with a 1
|
|||
|
||||
More about that topic can be viewed at  [Waiting in Rules](https://youtu.be/EdllUlJ7p6k?t=1600)
|
||||
|
||||
### After *period of time* Do With Timer
|
||||
### After _period of time_ Do With Timer
|
||||
|
||||

|
||||
|
||||
*Function:* Schedule a task to be performed once after a specific amount of time has elapsed.
|
||||
_Function:_ Schedule a task to be performed once after a specific amount of time has elapsed.
|
||||
|
||||
- A number and unit (seconds, minutes up to months) can be chosen after which the commands within the block will be executed
|
||||
- Provide the name of the timer, allowing further access to that timer within the same rule. The name also ensures the timer is unique within the rule.
|
||||
|
||||
*Example*
|
||||
_Example_
|
||||
|
||||
10 seconds after the rule has been called, the timer triggers all lights to go off:
|
||||
|
||||
|
@ -62,7 +62,7 @@ More about that topic can be viewed at 
|
||||
|
||||
|
@ -78,20 +78,20 @@ Setting up an endless timer in the above way is not recommended. The example sho
|
|||
|
||||

|
||||
|
||||
### After *period of time* Do With Timer with options on retriggering rule
|
||||
### After _period of time_ Do With Timer with options on retriggering rule
|
||||
|
||||

|
||||
|
||||
*Function:* Schedule a task to be performed at a specified period in the future with the ability to reschedule, cancel or ignore the timer **when the rule is retriggered**.
|
||||
_Function:_ Schedule a task to be performed at a specified period in the future with the ability to reschedule, cancel or ignore the timer **when the rule is retriggered**.
|
||||
|
||||
Before using that block, it is important to understand what the idea behind the option of retriggering:
|
||||
Though it may not seem to be obvious, the same rule can be retriggered at any time. To allow more control about what is happening in this case the rule is executed again, the following options are available:
|
||||
|
||||
**Options on Retrigger**
|
||||
|
||||
- *reschedule*: If the same rule that contains this Blockly script is re-triggered, and this specific timer is currently active, this specific timer will be rescheduled (i.e. restart the countdown timer).
|
||||
- *cancel*: If the same rule that contains this Blockly script is re-triggered, and this specific timer is currently active, this specific timer will be cancelled. The code within the timer will not be executed.
|
||||
- *do nothing*: If the same rule that contains this Blockly script is re-triggered, nothing happens - this will make the block identical to the simple timer-block in function, but the generated code is slightly modified - see below.
|
||||
- _reschedule_: If the same rule that contains this Blockly script is re-triggered, and this specific timer is currently active, this specific timer will be rescheduled (i.e. restart the countdown timer).
|
||||
- _cancel_: If the same rule that contains this Blockly script is re-triggered, and this specific timer is currently active, this specific timer will be cancelled. The code within the timer will not be executed.
|
||||
- _do nothing_: If the same rule that contains this Blockly script is re-triggered, nothing happens - this will make the block identical to the simple timer-block in function, but the generated code is slightly modified - see below.
|
||||
|
||||

|
||||
|
||||
|
@ -129,7 +129,7 @@ The retrigger timer-block inserts an additional `else{}` branch into the generat
|
|||
- the timer already exists and
|
||||
- the timer has not yet finished (it's still ticking)
|
||||
|
||||
In the case of *do nothing* the `else{}` branch is empty (which turns to be almost equals to the simle-timer).
|
||||
In the case of _do nothing_ the `else{}` branch is empty (which turns to be almost equals to the simle-timer).
|
||||
|
||||
```javascript
|
||||
if (typeof this.timers['nothingTimerBlock'] === 'undefined' || this.timers['nothingTimerBlock'].hasTerminated()) {
|
||||
|
@ -140,7 +140,7 @@ if (typeof this.timers['nothingTimerBlock'] === 'undefined' || this.timers['noth
|
|||
}
|
||||
```
|
||||
|
||||
In the case of *cancel* the `else{}` branch contains code to cancel the timer.
|
||||
In the case of _cancel_ the `else{}` branch contains code to cancel the timer.
|
||||
|
||||
```javascript
|
||||
if (typeof this.timers['cancelTimerBlock'] === 'undefined' || this.timers['cancelTimerBlock'].hasTerminated()) {
|
||||
|
@ -152,7 +152,7 @@ if (typeof this.timers['cancelTimerBlock'] === 'undefined' || this.timers['cance
|
|||
}
|
||||
```
|
||||
|
||||
In the case of *reschedule* the `else{}` statement contains code to reschedule the timer - restart the countdown. In the example generated code below:
|
||||
In the case of _reschedule_ the `else{}` statement contains code to reschedule the timer - restart the countdown. In the example generated code below:
|
||||
|
||||
- Imagine the rule is triggered at 0 elapsed seconds.
|
||||
- The timer is started with a 10 second countdown.
|
||||
|
@ -172,24 +172,24 @@ if (typeof this.timers['rescheduleTimerBlock'] === 'undefined' || this.timers['r
|
|||
### Cancel Timer
|
||||
|
||||

|
||||
*Function*: Cancels the existing named timer, preventing code within the timer block from executing.
|
||||
_Function_: Cancels the existing named timer, preventing code within the timer block from executing.
|
||||
|
||||
### Timer is Active
|
||||
|
||||

|
||||
|
||||
*Function:* returns `true` if the timer itself is currently counting down, and the code within the timer will be eventually executed as scheduled. This block will return `false` if the timer doesn't exist, has been cancelled, or has already finished.
|
||||
_Function:_ returns `true` if the timer itself is currently counting down, and the code within the timer will be eventually executed as scheduled. This block will return `false` if the timer doesn't exist, has been cancelled, or has already finished.
|
||||
|
||||
### Timer is Running
|
||||
|
||||

|
||||
|
||||
*Function*: returns `true` if the code *within the timer block* is currently running - i.e. the countdown has finished, and the code within the timer block is currently executing. This event will usually only last a few milliseconds, and you’d be (un)lucky to catch it when your rule retriggers.
|
||||
_Function_: returns `true` if the code _within the timer block_ is currently running - i.e. the countdown has finished, and the code within the timer block is currently executing. This event will usually only last a few milliseconds, and you’d be (un)lucky to catch it when your rule retriggers.
|
||||
|
||||
### Timer has terminated
|
||||
|
||||

|
||||
*Function*: returns `true` if the timer has finished its countdown, and the code within the timer block has finished running.
|
||||
_Function_: returns `true` if the timer has finished its countdown, and the code within the timer block has finished running.
|
||||
|
||||
### Comprehensive Timer Example
|
||||
|
||||
|
|
|
@ -10,15 +10,15 @@ title: Rules Blockly - Value Storage
|
|||
|
||||
## Introduction
|
||||
|
||||
These blocks enable storing information *for a rule* that is kept after the rule has run, so it can be reused when the rule is run again later in stateful way.
|
||||
These blocks enable storing information _for a rule_ that is kept after the rule has run, so it can be reused when the rule is run again later in stateful way.
|
||||
Basically a value storage can be perceived as a global variable for the rule instance.
|
||||
|
||||
- The values are persisted as a part of the *instance* of the rule
|
||||
- The values are persisted as a part of the _instance_ of the rule
|
||||
- Modifying the rule during development creates a new instance which means the value is reset.
|
||||
- Restarting openHAB creates a new rule instance which also means the value is reset
|
||||
- In most cases both situations are negligible for many rules.
|
||||
- If you need full persistence of values that can be used across rules you need to persist the value in one of the persistence engines like MapDB
|
||||
- By default the value is *undefined*.
|
||||
- By default the value is _undefined_.
|
||||
To check if a value is undefined, use the special "is undefined"-block
|
||||
|
||||
{::options toc_levels="2..4"/}
|
||||
|
|
|
@ -34,7 +34,7 @@ More about that topic can be viewed at 
|
||||
- Text-To-Speech
|
||||
- In order to use text-to-speech, you need to install at least one [TTS service](https://www.openhab.org/addons/#voice).
|
||||
|
@ -49,7 +49,7 @@ More about that topic can be viewed at 
|
||||
|
||||
*Function:* Plays an audio file on an audio sink
|
||||
_Function:_ Plays an audio file on an audio sink
|
||||
|
||||
- the audio file must reside in the sounds-folder of openHAB that can be found [here](https://community.openhab.org/t/blockly-reference/128785#openhab-configuration-files-7)
|
||||
- all available audio sinks are automatically provided by openHABs blocklies
|
||||
|
@ -60,7 +60,7 @@ Also view [Playing sounds on
|
|||
|
||||

|
||||
|
||||
*Function:* Plays an audio file on an audio sink and setting the volume at the same time
|
||||
_Function:_ Plays an audio file on an audio sink and setting the volume at the same time
|
||||
|
||||
same as above but also allowing to provide the volume at the same time
|
||||
|
||||
|
@ -80,7 +80,7 @@ In case this happens the more robust approach is as follows
|
|||
|
||||

|
||||
|
||||
*Function:* Starts an stream playing on an audio sink
|
||||
_Function:_ Starts an stream playing on an audio sink
|
||||
|
||||
- The audio streams must be reachable from the openHAB server and can therefore be either internally or externally hosted
|
||||
- All available audio sinks are automatically provided by openHAB's blocklies
|
||||
|
@ -92,13 +92,13 @@ More about that topic can be viewed at 
|
||||
|
||||
*Function:* Stops playing the current stream of the specified audio sink
|
||||
_Function:_ Stops playing the current stream of the specified audio sink
|
||||
|
||||
### Say
|
||||
|
||||

|
||||
|
||||
*Function:* Sends the given text to the sink by using the default Text-to-Speech-Service to translate the text based on the chosen language voice into a stream which is then played on that device sink.
|
||||
_Function:_ Sends the given text to the sink by using the default Text-to-Speech-Service to translate the text based on the chosen language voice into a stream which is then played on that device sink.
|
||||
|
||||
More about that topic can be viewed at [Using Text-to-speach easily with blocks](https://youtu.be/EdllUlJ7p6k?t=2403)
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ The steps required to set up a [network share](https://en.wikipedia.org/wiki/Sha
|
|||
How to setup and use Samba on a Linux system is described in the [Linux article]({{base}}/installation/linux.html#network-sharing).
|
||||
If you are using [openHABian]({{base}}/installation/openhabian.html), the network shares are readily configured for you, you only need to mount them locally.
|
||||
|
||||
*Attention Windows users:* Directly accessing network shares (UNC paths) is often not supported. Please be sure to mount the network share to a drive letter.
|
||||
_Attention Windows users:_ Directly accessing network shares (UNC paths) is often not supported. Please be sure to mount the network share to a drive letter.
|
||||
|
||||
{: #openhab-vscode}
|
||||
|
||||
|
|
|
@ -155,7 +155,7 @@ You must not create an item using files and then make use of it in the model usi
|
|||
text and system database configuration for that item, too.
|
||||
:::
|
||||
|
||||
You *can* configure the model through text only, too. No documentation exists for that however so it is not recommended and
|
||||
You _can_ configure the model through text only, too. No documentation exists for that however so it is not recommended and
|
||||
you have to figure out yourself. Please contribute to the docs here if you managed to.
|
||||
|
||||
Things/Items configured in files will become visible in Main UI if no Thing/Item of the same name is already present in the system database, but a lock will symbolize that you can NOT change them in the GUI. You can only change them by editing the source files.
|
||||
|
|
|
@ -197,7 +197,7 @@ Two naming schemes are established in the community for Group names:
|
|||
| "`Batteries`" or "`gBattery`" | Group combining the states of all battery Items |
|
||||
| "`Maintenance_Group`" or "`gMaintenance`" | Group containing all maintenance-related Items |
|
||||
| "`Livingroom_Lights`" or "`gLR_Light`" | Group containing all light Items belonging to the living room |
|
||||
| "`Livingroom`" or "`gLR`" | Group for *all* Items (including lights) belonging to the living room |
|
||||
| "`Livingroom`" or "`gLR`" | Group for _all_ Items (including lights) belonging to the living room |
|
||||
|
||||
{: #label}
|
||||
|
||||
|
@ -238,7 +238,7 @@ This section provides information about what a user can expect regarding the beh
|
|||
- A Binding may set the state of an Item to `UNDEF` if it looses communications with a Thing (for example, a Z-wave doorbell with a dead battery).
|
||||
The Binding may also set the state to `UNDEF` if an error exists in the binding configuration, or under other conditions
|
||||
|
||||
*N.B.* Many openHAB users find that it can be very useful to use [Persistence](/addons/#persistence) and [System started]({{base}}/configuration/rules-dsl.html#system-based-triggers) rules so that their systems behaves in a predictable way after an openHAB restart.
|
||||
_N.B._ Many openHAB users find that it can be very useful to use [Persistence](/addons/#persistence) and [System started]({{base}}/configuration/rules-dsl.html#system-based-triggers) rules so that their systems behaves in a predictable way after an openHAB restart.
|
||||
|
||||
{: #command-vs-status}
|
||||
|
||||
|
@ -637,10 +637,10 @@ The order of the parameters does not matter.
|
|||
|
||||
##### Parameter `autoupdate`
|
||||
|
||||
When left as default, openHAB's `autoupdate` function attempts to predict the outcome of a *command* on the Item *state*.
|
||||
When left as default, openHAB's `autoupdate` function attempts to predict the outcome of a _command_ on the Item _state_.
|
||||
This prediction may be influenced by any linked channels.
|
||||
`autoupdate="false"` is a special instruction which keeps the current state of the Item, even if a *command* has been received.
|
||||
This way, the Item is unchanged unless you explicitly post an *update* to the Item, or a binding updates it.
|
||||
`autoupdate="false"` is a special instruction which keeps the current state of the Item, even if a _command_ has been received.
|
||||
This way, the Item is unchanged unless you explicitly post an _update_ to the Item, or a binding updates it.
|
||||
`autoupdate="true"` forces `autoupdate` to act, overriding any binding recommendations.
|
||||
|
||||
Example:
|
||||
|
@ -655,7 +655,7 @@ Switch Garage_Gate {channel="xxx", autoupdate="false"}
|
|||
|
||||
This parameter allows to post an update or command to an item after a period of time has passed.
|
||||
|
||||
The expiration timer is started or restarted every time an item receives an update or a command *other than* the specified "expire" update/command.
|
||||
The expiration timer is started or restarted every time an item receives an update or a command _other than_ the specified "expire" update/command.
|
||||
Any future expiring update or command is cancelled, if the item receives an update or command that matches the "expire" update/command.
|
||||
|
||||
The parameter accepts a duration of time that can be a combination of hours, minutes and seconds in the format
|
||||
|
@ -687,7 +687,7 @@ Without the quotes, the state would be the system type `UNDEF`.
|
|||
#### Profiles
|
||||
|
||||
With Profiles, you are able to change the behavior how Channels interact with your Items.
|
||||
You can use *State Profiles* on State Channels and *Trigger Profiles* on Trigger Channels.
|
||||
You can use _State Profiles_ on State Channels and _Trigger Profiles_ on Trigger Channels.
|
||||
|
||||
Profiles can be specified as a parameter for a given Channel on the Item configuration:
|
||||
|
||||
|
@ -745,7 +745,7 @@ then
|
|||
end
|
||||
```
|
||||
|
||||
Instead of using this Rule, you can also use the `rawbutton-toggle-switch` Profile in combination with [Multi-Channel Linking](#multi-binding-channel-linkage):
|
||||
Instead of using this Rule, you can also use the `rawbutton-toggle-switch` Profile in combination with [Multi-Channel Linking](#multi-binding--channel-linkage):
|
||||
|
||||
```java
|
||||
Color Bedroom_Light {
|
||||
|
|
|
@ -24,7 +24,7 @@ and comes with a well documented helper library ([openhab-js](https://github.com
|
|||
|
||||
Although JSR223 scripts can be used as a general-purpose extension language for openHAB, it is most commonly used for the creation of rules, and within scripted Actions or Conditions.
|
||||
Currently, openHAB allows JSR223 scripting to access all packages, which may not be included in the official APIs.
|
||||
This provides great flexibility for the users of JSR223, but is also *use at your own risk*, since changes outside of the official APIs occur frequently, and are not considered to be *breaking changes*.
|
||||
This provides great flexibility for the users of JSR223, but is also _use at your own risk_, since changes outside of the official APIs occur frequently, and are not considered to be _breaking changes_.
|
||||
New APIs are planned to be implemented in the future, which will provide standardized interfaces for interacting with openHAB through scripted automation.
|
||||
|
||||
### Example rules for a first impression
|
||||
|
@ -225,10 +225,10 @@ To faciliate JSR223 scripting, several openHAB-related variables are automatical
|
|||
They can be loaded into the script context using `scriptExtension.importPreset(String preset)`, e.g. `scriptExtension.importPreset("RuleSimple")`.
|
||||
The `default` preset is preloaded, so it does not require importing.
|
||||
|
||||
- [`Default`](#default_presets)
|
||||
- [`RuleSimple`](#rulesimple_presets)
|
||||
- [`RuleSupport`](#rulesupport_presets)
|
||||
- [`RuleFactories`](#rulefactories_presets)
|
||||
- [`Default`](#default-preset-importpreset-not-required)
|
||||
- [`RuleSimple`](#rulesimple-preset)
|
||||
- [`RuleSupport`](#rulesupport-preset)
|
||||
- [`RuleFactories`](#rulefactories-preset)
|
||||
|
||||
#### Default Preset (`importPreset` not required)
|
||||
|
||||
|
@ -289,7 +289,7 @@ The `default` preset is preloaded, so it does not require importing.
|
|||
| `itemRegistry` | Instance of `org.openhab.core.items.ItemRegistry` |
|
||||
| `things` | Instance of `org.openhab.core.thing.ThingRegistry` |
|
||||
| `rules` | Instance of `org.openhab.core.automation.RuleRegistry` |
|
||||
| `events` | (internal) Used to send events, post commands, etc. [Details](#event_operations) below] |
|
||||
| `events` | (internal) Used to send events, post commands, etc. [Details](#events-operations) below] |
|
||||
| `actions` | Instance of `org.openhab.core.thing.binding.ThingActions` |
|
||||
| `scriptExtension` | (internal) For loading script presets. |
|
||||
| `se` | Alias for `scriptExtension` |
|
||||
|
|
|
@ -10,7 +10,7 @@ title: Rules
|
|||
Note that there is also a visual way of programming openHAB rules, which may be more suitable for beginners. Its documentation can be found in the [Blockly Reference section]({{base}}/configuration/rules-blockly.html)
|
||||
|
||||
openHAB has a highly integrated, lightweight but yet powerful rule engine included.
|
||||
On this page you will learn how to leverage its functionality to do *real* home automation.
|
||||
On this page you will learn how to leverage its functionality to do _real_ home automation.
|
||||
|
||||
{::options toc_levels="2..4"/}
|
||||
|
||||
|
@ -358,7 +358,7 @@ The following table summarizes the impact of the two manipulator commands on the
|
|||
|--------------------------|-------------------|--------------------|-----------|
|
||||
| postUpdate | ⚡ rule fires | ❌ | (depends) |
|
||||
| sendCommand | (❌) see below | ⚡ rule fires | (depends) |
|
||||
| *Change through Binding* | ⚡ rule fires | ⚡ rule fires | (depends) |
|
||||
| _Change through Binding_ | ⚡ rule fires | ⚡ rule fires | (depends) |
|
||||
|
||||
**Beware:**
|
||||
In most cases, a rule with a trigger of `received update` will fire following the command `sendCommand` as:
|
||||
|
@ -389,7 +389,7 @@ Using `Myitem.sendCommand(new_state)` or `Myitem.postUpdate(new_state)` will, in
|
|||
The Action `sendCommand(MyItem, new_state)` does not provide the same flexibilty.
|
||||
For example, if `new_state` is typed as a primitive (e.g., `var int new_state = 3`) and myItem is of the Object type Dimmer:
|
||||
|
||||
- the following command ***will fail***: ~~sendCommand(MyItem, new_state)~~.
|
||||
- the following command _**will fail**_: ~~sendCommand(MyItem, new_state)~~.
|
||||
- However, the following command **will work**: `MyItem.sendCommand(new_state)`.
|
||||
|
||||
Using `MyItem.postUpdate(new_state)` or `MyItem.sendCommand(new_state)` will create the most stable code.
|
||||
|
@ -449,7 +449,7 @@ There are two ways to discover these methods:
|
|||
|
||||
#### Working with Item States: Conversions
|
||||
|
||||
*Reminder: For a complete and up-to-date list of what item types are currently allowed in openHAB and the command types each item can accept refer to the section on [items in the openHAB documentation]({{base}}/concepts/items.html).*
|
||||
_Reminder: For a complete and up-to-date list of what item types are currently allowed in openHAB and the command types each item can accept refer to the section on [items in the openHAB documentation]({{base}}/concepts/items.html)._
|
||||
|
||||
Below a **non-exhaustive** list of some more common conversions.
|
||||
The interested reader is encouraged to also visit the [forum](https://community.openhab.org) where many more examples can be found.
|
||||
|
@ -835,7 +835,7 @@ transform("<transformation-identifier>", "<transf. expression or transf. file na
|
|||
|
||||
- `<transformation-identifier>` - Shorthand identifier of the transformation service
|
||||
- `<transf. expression or transf. file name>` - Transformation service specific
|
||||
- `<input-data or variable>` - The data to transform, MUST be of data type *String*
|
||||
- `<input-data or variable>` - The data to transform, MUST be of data type _String_
|
||||
|
||||
Examples:
|
||||
|
||||
|
|
|
@ -628,7 +628,7 @@ The composite module type wraps one or more instances of a system module type an
|
|||
}
|
||||
```
|
||||
|
||||
This example demonstrates a new module type *ItemStateChangeTrigger* which wraps the system module type *GenericEventTrigger*.
|
||||
It defines the new configuration property `itemName` which is used as the `eventSource` property of the *GenericEventTrigger*.
|
||||
This example demonstrates a new module type _ItemStateChangeTrigger_ which wraps the system module type _GenericEventTrigger_.
|
||||
It defines the new configuration property `itemName` which is used as the `eventSource` property of the _GenericEventTrigger_.
|
||||
The other config parameters `eventTopic` and `eventTypes` are staticly defined.
|
||||
The composite module type can also have inputs and outputs and can use a reference to map them to inputs and outputs of the nested system module type(s).
|
||||
|
|
|
@ -11,7 +11,7 @@ Background information: The meta information of all bindings is accessible throu
|
|||
|
||||
Although binding definitions are usually specified in a declarative way (as described in this section),
|
||||
they can also be provided as `org.openhab.core.binding.BindingInfo`.
|
||||
Any `BindingInfo` must be registered as service at the *OSGi* service registry.
|
||||
Any `BindingInfo` must be registered as service at the _OSGi_ service registry.
|
||||
The full Java API for binding definitions can be found in the Java package `org.openhab.core.binding`.
|
||||
|
||||
For the declarative way, you add your binding information in form of a `binding.xml` file to the bundle's folder `/src/main/resources/OH-INF/binding/binding.xml`.
|
||||
|
@ -52,7 +52,7 @@ The full XML schema for binding definitions is specified in the [Binding XSD](ht
|
|||
|
||||
**Hints:**
|
||||
|
||||
- The attribute `uri` in the section `config-description` is optional, it *should not* be specified in binding definition files because it's an embedded configuration. If the `uri` is *not* specified, the configuration description is registered as `binding:bindingID`, otherwise the given `uri` is used.
|
||||
- The attribute `uri` in the section `config-description` is optional, it _should not_ be specified in binding definition files because it's an embedded configuration. If the `uri` is _not_ specified, the configuration description is registered as `binding:bindingID`, otherwise the given `uri` is used.
|
||||
- If a configuration description is already specified somewhere else and the binding wants to (re-)use it, a `config-description-ref` should be used instead.
|
||||
- Normally the service id must not be defined, because it is implicitly set to "binding.<binding.id>".
|
||||
A binding can register an OSGi service which implements the ManagedService interface and define the service.pid as e.g."binding.hue" to receive the configuration.
|
||||
|
|
|
@ -10,7 +10,7 @@ To visualize or validate concrete configuration properties, configuration descri
|
|||
All available configuration descriptions are accessible through the `org.openhab.core.config.core.ConfigDescriptionRegistry` service.
|
||||
|
||||
Although configuration descriptions are usually specified in a declarative way (as described in this section), they can also be provided as `org.openhab.core.config.core.ConfigDescriptionProvider`.
|
||||
Any `ConfigDescriptionProvider`s must be registered as service at the *OSGi* service registry.
|
||||
Any `ConfigDescriptionProvider`s must be registered as service at the _OSGi_ service registry.
|
||||
The full Java API for configuration descriptions can be found in the Java package `org.openhab.core.config.core`.
|
||||
In addition to this there is a `org.openhab.core.config.core.validation.ConfigDescriptionValidator` that can be used to validate a set of configuration parameters against their declarations in the configuration description before the actual configuration is updated with the new configuration parameters.
|
||||
|
||||
|
@ -176,7 +176,7 @@ The full XML schema for configuration descriptions is specified in the [openHAB
|
|||
|
||||
**Hints:**
|
||||
|
||||
- Although the attribute `uri` is optional, it *must* be specified in configuration description files.
|
||||
- Although the attribute `uri` is optional, it _must_ be specified in configuration description files.
|
||||
Only for embedded configuration descriptions in documents for binding definitions and `Thing` type descriptions, the attribute is optional.
|
||||
|
||||
## Example
|
||||
|
|
|
@ -8,7 +8,7 @@ title: Bindings
|
|||
{:.no_toc}
|
||||
|
||||
A binding is an extension to openHAB that integrates an external system like a software service or a hardware device.
|
||||
The external system is represented as a set of *Things* and sometimes *Bridges* with *Channels*.
|
||||
The external system is represented as a set of _Things_ and sometimes _Bridges_ with _Channels_.
|
||||
|
||||
This chapter covers everything to know about binding development.
|
||||
It makes sense to briefly read over all sections to make you familiar with what the framework has to offer.
|
||||
|
@ -29,28 +29,28 @@ Find more information in the respective [binding XML reference](binding-xml.html
|
|||
|
||||
## Describing Things
|
||||
|
||||
External systems are represented as *Things* in openHAB.
|
||||
External systems are represented as _Things_ in openHAB.
|
||||
When starting the implementation of a binding, you should think about the abstraction of your external system.
|
||||
Different services or devices should be represented as individual *Things*.
|
||||
Each functionality of the *Thing* should be modelled as a `Channel`.
|
||||
Different services or devices should be represented as individual _Things_.
|
||||
Each functionality of the _Thing_ should be modelled as a `Channel`.
|
||||
|
||||
*Thing* and *Channel* structures need to be explained to the openHAB runtime.
|
||||
This is done in a declarative way via XML files, so called *ThingTypes* and *ChannelTypes*.
|
||||
_Thing_ and _Channel_ structures need to be explained to the openHAB runtime.
|
||||
This is done in a declarative way via XML files, so called _ThingTypes_ and _ChannelTypes_.
|
||||
|
||||
Find more information in the respective [Thing & Channel XML reference](thing-xml.html).
|
||||
|
||||
## The ThingHandlerFactory
|
||||
|
||||
For each *Thing* the binding must provide a proper `ThingHandler` implementation that is able to handle the communication.
|
||||
For each _Thing_ the binding must provide a proper `ThingHandler` implementation that is able to handle the communication.
|
||||
|
||||
The `ThingHandlerFactory` is responsible for creating `ThingHandler` instances.
|
||||
|
||||
Every binding must implement a `ThingHandlerFactory` and register it as OSGi service so that the runtime knows which class needs to be called for creating and handling things.
|
||||
|
||||
When a new *Thing* is added, the openHAB runtime queries every `ThingHandlerFactory` for support of the *ThingType* by calling the `supportsThingType` method.
|
||||
When a new _Thing_ is added, the openHAB runtime queries every `ThingHandlerFactory` for support of the _ThingType_ by calling the `supportsThingType` method.
|
||||
When the method returns `true`, the runtime calls `createHandler`, which should then return a proper `ThingHandler` implementation.
|
||||
|
||||
A weather bindings `WeatherHandlerFactory` for example supports only one *ThingType* and instantiates a new `WeatherHandler` for a given thing:
|
||||
A weather bindings `WeatherHandlerFactory` for example supports only one _ThingType_ and instantiates a new `WeatherHandler` for a given thing:
|
||||
|
||||
```java
|
||||
@NonNullByDefault
|
||||
|
@ -77,10 +77,10 @@ public class WeatherHandlerFactory extends BaseThingHandlerFactory {
|
|||
}
|
||||
```
|
||||
|
||||
Constants like the `THING_TYPE_WEATHER` UID and also *Channel* UIDs are typically defined inside a public `BindingConstants` class.
|
||||
Constants like the `THING_TYPE_WEATHER` UID and also _Channel_ UIDs are typically defined inside a public `BindingConstants` class.
|
||||
|
||||
Depending on your implementation, each *ThingType* may use its own handler.
|
||||
It is also possible to use the same handler for different *Things*, or use different handlers for the same *ThingType*, depending on the configuration.
|
||||
Depending on your implementation, each _ThingType_ may use its own handler.
|
||||
It is also possible to use the same handler for different _Things_, or use different handlers for the same _ThingType_, depending on the configuration.
|
||||
|
||||
## The ThingHandler
|
||||
|
||||
|
@ -133,14 +133,14 @@ The `ThingManager` creates for each Thing a `ThingHandler` instance using a `Thi
|
|||
Therefore, it tracks all `ThingHandlerFactory`s from the binding.
|
||||
|
||||
The `ThingManager` determines if the `Thing` is initializable or not.
|
||||
A `Thing` is considered as *initializable* if all *required* configuration parameters (cf. property *parameter.required* in [Configuration Description](config-xml.html)) are available.
|
||||
A `Thing` is considered as _initializable_ if all _required_ configuration parameters (cf. property _parameter.required_ in [Configuration Description](config-xml.html)) are available.
|
||||
If so, the method `ThingHandler.initialize()` is called.
|
||||
|
||||
Only Things with status (cf. [Thing Status](../../concepts/things.html#thing-status)) *UNKNOWN*, *ONLINE* or *OFFLINE* are considered as *initialized* by the framework and therefore it is the handler's duty to assign one of these states sooner or later.
|
||||
Only Things with status (cf. [Thing Status](../../concepts/things.html#thing-status)) _UNKNOWN_, _ONLINE_ or _OFFLINE_ are considered as _initialized_ by the framework and therefore it is the handler's duty to assign one of these states sooner or later.
|
||||
To achieve that, the status must be reported to the framework via the callback or `BaseThingHandler.updateStatus(...)` for convenience.
|
||||
Furthermore, the framework expects `initialize()` to be non-blocking and to return quickly.
|
||||
For longer running initializations, the implementation has to take care of scheduling a separate job which must guarantee to set the status eventually.
|
||||
Also, please note that the framework expects the `initialize()` method to handle anticipated error situations gracefully and set the thing to *OFFLINE* with the corresponding status detail (e.g. *COMMUNICATION_ERROR* or *CONFIGURATION_ERROR* including a meaningful description) instead of throwing exceptions.
|
||||
Also, please note that the framework expects the `initialize()` method to handle anticipated error situations gracefully and set the thing to _OFFLINE_ with the corresponding status detail (e.g. _COMMUNICATION_ERROR_ or _CONFIGURATION_ERROR_ including a meaningful description) instead of throwing exceptions.
|
||||
|
||||
If the `Thing` is not initializable the configuration can be updated via `ThingHandler.handleConfigurationUpdate(Map)`.
|
||||
The binding has to notify the `ThingManager` about the updated configuration by a callback.
|
||||
|
@ -165,18 +165,18 @@ After the handler is disposed, the framework will not call the handler anymore.
|
|||
|
||||
#### Bridge Status Changes
|
||||
|
||||
A `ThingHandler` is notified about Bridge status changes to *ONLINE* and *OFFLINE* after a `BridgeHandler` has been initialized.
|
||||
A `ThingHandler` is notified about Bridge status changes to _ONLINE_ and _OFFLINE_ after a `BridgeHandler` has been initialized.
|
||||
Therefore, the method `ThingHandler.bridgeStatusChanged(ThingStatusInfo)` must be implemented
|
||||
(this method is not called for a bridge status updated through the bridge initialization itself).
|
||||
If the Thing of this handler does not have a Bridge, this method is never called.
|
||||
|
||||
If the bridge status has changed to OFFLINE, the status of the handled thing must also be updated to *OFFLINE* with detail *BRIDGE_OFFLINE*.
|
||||
If the bridge returns to *ONLINE*, the thing status must be changed at least to *OFFLINE* with detail *NONE* or to another thing specific status.
|
||||
If the bridge status has changed to OFFLINE, the status of the handled thing must also be updated to _OFFLINE_ with detail _BRIDGE_OFFLINE_.
|
||||
If the bridge returns to _ONLINE_, the thing status must be changed at least to _OFFLINE_ with detail _NONE_ or to another thing specific status.
|
||||
|
||||
### Configuration
|
||||
|
||||
*Things* can be configured with parameters.
|
||||
To retrieve the configuration of a *Thing* one can call `getThing().getConfiguration()` inside the `ThingHandler`.
|
||||
_Things_ can be configured with parameters.
|
||||
To retrieve the configuration of a _Thing_ one can call `getThing().getConfiguration()` inside the `ThingHandler`.
|
||||
The configuration class has the equivalent methods as the `Map` interface, thus the method `get(String key)` can be used to retrieve a value for a given key.
|
||||
|
||||
Moreover the configuration class has a utility method `as(Class<T> configurationClass)` that transforms the configuration into a Java object of the given type.
|
||||
|
@ -187,7 +187,7 @@ The following types are supported for configuration values: `Boolean`, `boolean`
|
|||
|
||||
### Properties
|
||||
|
||||
*Things* can have properties.
|
||||
_Things_ can have properties.
|
||||
If you would like to add meta data to your thing, e.g. the vendor of the thing, then you can define your own thing properties by simply adding them to the thing type definition.
|
||||
The properties section [here](thing-xml.html#properties) explains how to specify such properties.
|
||||
|
||||
|
@ -199,7 +199,7 @@ In contrast to the `getProperties` operation of the thing type instance the resu
|
|||
### Handling Commands
|
||||
|
||||
For handling commands the `ThingHandler` interface defines the `handleCommand` method.
|
||||
This method is called when a command is sent to an item, which is linked to a channel of the *Thing*.
|
||||
This method is called when a command is sent to an item, which is linked to a channel of the _Thing_.
|
||||
A Command represents the intention that an action should be executed on the external system,
|
||||
or that the state should be changed.
|
||||
Inside the `handleCommand` method binding specific logic can be executed.
|
||||
|
@ -327,8 +327,8 @@ It is binding specific when the channel should be triggered.
|
|||
|
||||
### Updating the Thing Status
|
||||
|
||||
The *ThingHandler* must also manage the thing status (see also: [Thing Status Concept](../../concepts/things.html#thing-status)).
|
||||
If the device or service is not working correctly, the binding should change the status to *OFFLINE* and back to *ONLINE*, if it is working again.
|
||||
The _ThingHandler_ must also manage the thing status (see also: [Thing Status Concept](../../concepts/things.html#thing-status)).
|
||||
If the device or service is not working correctly, the binding should change the status to _OFFLINE_ and back to _ONLINE_, if it is working again.
|
||||
The status can be updated via an inherited method from the BaseThingHandler class by calling:
|
||||
|
||||
```java
|
||||
|
@ -346,8 +346,8 @@ updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.COMMUNICATION_ERROR,
|
|||
```
|
||||
|
||||
After the thing is created, the framework calls the `initialize` method of the handler.
|
||||
At this time the state of the thing is *INTIALIZING* as long as the binding sets it to something else.
|
||||
Because of this the default implementation of the `initialize()` method in the `BaseThingHandler` just changes the status to *ONLINE*.
|
||||
At this time the state of the thing is _INTIALIZING_ as long as the binding sets it to something else.
|
||||
Because of this the default implementation of the `initialize()` method in the `BaseThingHandler` just changes the status to _ONLINE_.
|
||||
|
||||
::: tip Note
|
||||
A binding should not set any other state than ONLINE, OFFLINE and UNKNOWN.
|
||||
|
@ -458,17 +458,17 @@ the framework does not call the `thingUpdated` method to avoid infinite loops.
|
|||
|
||||
In the domain of an IoT system there are often hierarchical structures of devices and services.
|
||||
For example, one device acts as a gateway that enables communication with other devices that use the same protocol.
|
||||
In openHAB this kind of device or service is called *Bridge*.
|
||||
In openHAB this kind of device or service is called _Bridge_.
|
||||
Philips Hue is one example of a system that requires a bridge.
|
||||
The Hue gateway is an IP device with an HTTP API, which communicates over the ZigBee protocol with the Hue bulbs.
|
||||
In the openHAB model the Hue gateway is represented as a *Bridge* with connected *Things*, that represent the Hue bulbs.
|
||||
*Bridge* inherits from *Thing*, so that it also has *Channels* and all other features of a thing, with the addition that it also holds a list of things.
|
||||
In the openHAB model the Hue gateway is represented as a _Bridge_ with connected _Things_, that represent the Hue bulbs.
|
||||
_Bridge_ inherits from _Thing_, so that it also has _Channels_ and all other features of a thing, with the addition that it also holds a list of things.
|
||||
|
||||
We have a FAQ, dicussing [Thing, Bridge and Channel modelling](faq.html#structuring-things-and-thing-types).
|
||||
|
||||
When implementing a binding with *Bridges*, the logic to communicate with the external system is often shared between the different `ThingHandler` implementations.
|
||||
In that case it makes sense to implement a handler for the *Bridge* and delegate the actual command execution from the *ThingHandler* to the *BridgeHandler*.
|
||||
To access the *BridgeHandler* from the *ThingHandler*, call `getBridge().getHandler()`
|
||||
When implementing a binding with _Bridges_, the logic to communicate with the external system is often shared between the different `ThingHandler` implementations.
|
||||
In that case it makes sense to implement a handler for the _Bridge_ and delegate the actual command execution from the _ThingHandler_ to the _BridgeHandler_.
|
||||
To access the _BridgeHandler_ from the _ThingHandler_, call `getBridge().getHandler()`
|
||||
|
||||
The following excerpt shows how the `HueLightHandler` delegates the command for changing the light state to the `HueBridgeHandler`:
|
||||
|
||||
|
@ -489,11 +489,11 @@ public void handleCommand(ChannelUID channelUID, Command command) {
|
|||
}
|
||||
```
|
||||
|
||||
Inside the `BridgeHandler` the list of *Things* can be retrieved via the `getThings()` call.
|
||||
Inside the `BridgeHandler` the list of _Things_ can be retrieved via the `getThings()` call.
|
||||
|
||||
### Bridge Handler Implementation
|
||||
|
||||
A `BridgeHandler` handles the communication between the openHAB framework and a *bridge* (a device that acts as a gateway to enable the communication with other devices) represented by a `Bridge` instance.
|
||||
A `BridgeHandler` handles the communication between the openHAB framework and a _bridge_ (a device that acts as a gateway to enable the communication with other devices) represented by a `Bridge` instance.
|
||||
|
||||
A bridge handler has the same properties as thing handler.
|
||||
Therefore, the `BridgeHandler` interface extends the `ThingHandler` interface.
|
||||
|
@ -506,7 +506,7 @@ It is recommended to use this class, because it covers a lot of common logic.
|
|||
### Life cycle
|
||||
|
||||
A `BridgeHandler` has the same life cycle than a `ThingHandler` (created by a `ThingHandlerFactory`, well defined life cycle by handler methods `initialize()` and `dispose()`, see chapter [Life Cycle](#lifecycle)).
|
||||
A bridge acts as a gateway in order to provide access to other devices, the *child things*.
|
||||
A bridge acts as a gateway in order to provide access to other devices, the _child things_.
|
||||
Hence, the life cycle of a child handler depends on the life cycle of a bridge handler.
|
||||
Bridge and child handlers are subject to the following restrictions:
|
||||
|
||||
|
@ -530,7 +530,7 @@ For this purpose the handler of the entity implements the interface `org.openhab
|
|||
|
||||
### Providing the Configuration Status
|
||||
|
||||
A *ThingHandler* as handler for the thing entity can provide the configuration status of the thing by implementing the `org.openhab.core.config.core.status.ConfigStatusProvider` interface.
|
||||
A _ThingHandler_ as handler for the thing entity can provide the configuration status of the thing by implementing the `org.openhab.core.config.core.status.ConfigStatusProvider` interface.
|
||||
|
||||
For things that are created by sub-classes of the `BaseThingHandlerFactory` the provider is already automatically registered as an OSGi service if the concrete thing handler implements the configuration status provider interface.
|
||||
Currently the framework provides two base thing handler implementations for the configuration status provider interface:
|
||||
|
@ -545,7 +545,7 @@ Sub-classes of these handlers must only override the operation `getConfigStatus`
|
|||
The framework will take care of internationalizing messages.
|
||||
|
||||
For this purpose there must be an [i18n](../utils/i18n.html) properties file inside the bundle of the configuration status provider that has a message declared for the message key of the `ConfigStatusMessage`.
|
||||
The actual message key is built by the operation `withMessageKeySuffix(String)` of the message´s builder in the manner that the given message key suffix is appended to *config-status."config-status-message-type."*.
|
||||
The actual message key is built by the operation `withMessageKeySuffix(String)` of the message´s builder in the manner that the given message key suffix is appended to _config-status."config-status-message-type."_.
|
||||
|
||||
As a result depending on the type of the message the final constructed message keys are:
|
||||
|
||||
|
@ -658,7 +658,7 @@ The following table gives an overview about the main parts of a `DiscoveryResult
|
|||
|
||||
| Field | Description |
|
||||
|-------|-------------|
|
||||
| `thingUID` | The `thingUID` is the unique identifier of the specific discovered thing (e.g. a device's serial number). It *must not* be constructed out of properties, that can change (e.g. IP addresses). A typical `thingUID` could look like this: `hue:bridge:001788141f1a`
|
||||
| `thingUID` | The `thingUID` is the unique identifier of the specific discovered thing (e.g. a device's serial number). It _must not_ be constructed out of properties, that can change (e.g. IP addresses). A typical `thingUID` could look like this: `hue:bridge:001788141f1a`
|
||||
| `thingTypeUID` | Contrary to the `thingUID` is the `thingTypeUID` that specifies the type the discovered thing belongs to. It could be constructed from e.g. a product number. A typical `thingTypeUID` could be the following: `hue:bridge`.
|
||||
| `bridgeUID` | If the discovered thing belongs to a bridge, the `bridgeUID` contains the UID of that bridge.
|
||||
| `properties` | The `properties` of a `DiscoveryResult` contain the configuration for the newly created thing.
|
||||
|
@ -1080,5 +1080,5 @@ Also, JPEG compression artifacts from prior conversions or halo around the logo
|
|||
There are online converters to convert your True Color PNG logo to Palette-Based Colors. E.g. <https://compresspng.com/>.
|
||||
Or use zopflipng: `zopflipng -m --filters=0me --lossy_8bit --lossy_transparent -y logo.png logo.png`
|
||||
|
||||
*After* your binding's pull request has been merged, you can upload your logo by filing another pull request to the [openhab-docs/images/addons/](https://github.com/openhab/openhab-docs/tree/main/images/addons) repository.
|
||||
_After_ your binding's pull request has been merged, you can upload your logo by filing another pull request to the [openhab-docs/images/addons/](https://github.com/openhab/openhab-docs/tree/main/images/addons) repository.
|
||||
Your logo will be available after the next website build.
|
||||
|
|
|
@ -7,7 +7,7 @@ title: Thing Descriptions
|
|||
|
||||
{:.no_toc}
|
||||
|
||||
In order to work with *Things* and *Channels*, some meta information about them is needed.
|
||||
In order to work with _Things_ and _Channels_, some meta information about them is needed.
|
||||
|
||||
These are provided through 'ThingType' and 'ChannelType' definitions,
|
||||
which describe details about their functionality and configuration options.
|
||||
|
@ -604,14 +604,14 @@ The following policies are supported:
|
|||
|
||||
## Bridges and Thing Descriptions
|
||||
|
||||
Every binding has to provide meta information about which bridges and/or *Thing*s it provides and how their relations to each other are structured.
|
||||
Every binding has to provide meta information about which bridges and/or _Thing_s it provides and how their relations to each other are structured.
|
||||
In that way a binding could describe that it requires specific bridges to be operational or define which channels (e.g. temperature, color, etc.) it provides.
|
||||
|
||||
Every bridge or *Thing* has to provide meta information such as label or description.
|
||||
The meta information of all bridges and *Thing*s is accessible through the `org.openhab.core.thing.binding.ThingTypeProvider` service.
|
||||
Every bridge or _Thing_ has to provide meta information such as label or description.
|
||||
The meta information of all bridges and _Thing_s is accessible through the `org.openhab.core.thing.binding.ThingTypeProvider` service.
|
||||
|
||||
Bridge and *Thing* descriptions must be placed as XML file(s) (with the ending `.xml`) in the bundle's folder `/OH-INF/thing/`.
|
||||
The full Java API for bridge and *Thing* descriptions can be found in the Java package `org.openhab.core.thing.type`.
|
||||
Bridge and _Thing_ descriptions must be placed as XML file(s) (with the ending `.xml`) in the bundle's folder `/OH-INF/thing/`.
|
||||
The full Java API for bridge and _Thing_ descriptions can be found in the Java package `org.openhab.core.thing.type`.
|
||||
|
||||
### XML Structure for Thing Descriptions
|
||||
|
||||
|
@ -851,6 +851,6 @@ The full XML schema for Thing type descriptions is specified in the [https://ope
|
|||
**Hints:**
|
||||
|
||||
- Any identifiers of the types are automatically mapped to unique identifiers: `bindingID:id`.
|
||||
- The attribute `uri` in the section `config-description` is optional, it *should not* be specified in bridge/*Thing*/channel type definition files because it's an embedded configuration.
|
||||
If the `uri` is *not* specified, the configuration description is registered as `thing-type:bindingID:id` or `channel-type:bindingID:id` otherwise the given `uri` is used.s
|
||||
- If a configuration description is already specified somewhere else and the bridge/*Thing*/channel type wants to (re-)use it, a `config-description-ref` should be used instead.
|
||||
- The attribute `uri` in the section `config-description` is optional, it _should not_ be specified in bridge/_Thing_/channel type definition files because it's an embedded configuration.
|
||||
If the `uri` is _not_ specified, the configuration description is registered as `thing-type:bindingID:id` or `channel-type:bindingID:id` otherwise the given `uri` is used.s
|
||||
- If a configuration description is already specified somewhere else and the bridge/_Thing_/channel type wants to (re-)use it, a `config-description-ref` should be used instead.
|
||||
|
|
|
@ -29,7 +29,7 @@ If there's a problem with the implementation, hopefully you received feedback on
|
|||
We're trying very hard to keep openHAB lean and focused.
|
||||
We don't want it to do everything for everybody.
|
||||
This means that we might decide against incorporating a new feature.
|
||||
However, there might be a way to implement that feature *on top of* openHAB.
|
||||
However, there might be a way to implement that feature _on top of_ openHAB.
|
||||
|
||||
### Discuss Your Design in the Community
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ openHAB allows you to build upon the following concepts:
|
|||
|
||||
- **Bindings**: A binding connects to external services or devices.
|
||||
- **Automation engine module**: A trigger, condition, or action that can be used in automation rules (or scripts).
|
||||
- **Transformation / Profiles**: Can be used to transform a *Thing Channel*- value before it is assigned to an *Item*.
|
||||
- **Transformation / Profiles**: Can be used to transform a _Thing Channel_- value before it is assigned to an _Item_.
|
||||
- **An IO service**: Exposes openHAB internals via a defined interface (for example the REST interface, HomeKit or Hue Emulation Service).
|
||||
- **A Persistence service**: Persist item state updates and/or changes and allows them to be retrieved for specific points in time.
|
||||
- **Natural language processing skill**:
|
||||
|
|
|
@ -7,7 +7,7 @@ title: Automation Modules
|
|||
|
||||
{:.no_toc}
|
||||
|
||||
In this section you will be guided through developing *Module Types* and corresponding *Module Handlers* for the automation engine of openHAB.
|
||||
In this section you will be guided through developing _Module Types_ and corresponding _Module Handlers_ for the automation engine of openHAB.
|
||||
|
||||
{::options toc_levels="2,3"/}
|
||||
|
||||
|
@ -19,7 +19,7 @@ In this section you will be guided through developing *Module Types* and corresp
|
|||
Module Types describe Conditions, Triggers and Actions for the automation engine in terms of user visible strings like a label, a description, tags.
|
||||
But also what configuration values are available and what inputs and outputs a Module Type provides.
|
||||
|
||||
For each *Module Type* a corresponding *Module Handler* is in place to actually execute code.
|
||||
For each _Module Type_ a corresponding _Module Handler_ is in place to actually execute code.
|
||||
|
||||
To better get into the topic, let's develop a rule for the automation engine that is compromised completely out of custom modules (in contrast to core provided ones).
|
||||
|
||||
|
@ -81,7 +81,7 @@ public class MyModuleTypeProvider implements ModuleTypeProvider {
|
|||
}
|
||||
```
|
||||
|
||||
The above factory is exposing all three *Module Types* that we need for our scenario.
|
||||
The above factory is exposing all three _Module Types_ that we need for our scenario.
|
||||
We do not need to care about the `ProviderChangeListener` methods here, because our types are rather static.
|
||||
If module types change over time in your factory, you need to notify the automation engine.
|
||||
|
||||
|
@ -134,7 +134,7 @@ A configuration parameter needs a unique ID, a label, optionally a description a
|
|||
Triggers and Conditions can also output data.
|
||||
And our temperature trigger will not only trigger on a configured temperature, but also output it.
|
||||
|
||||
To define an *Output* you need to pass at least an ID, a type, a label and a description to the constructor.
|
||||
To define an _Output_ you need to pass at least an ID, a type, a label and a description to the constructor.
|
||||
The type is the fully qualified name of a class, in this case from the `Integer` class.
|
||||
|
||||
Conditions and Actions can take inputs on the other hand.
|
||||
|
@ -178,9 +178,9 @@ The Condition that we are going to implement in the Condition Handler latter on
|
|||
Notice that our output is of type "State" instead of a fully qualified class name like `java.lang.String`.
|
||||
The following openHAB classes have short forms:
|
||||
|
||||
- "State" (an *Item* state)
|
||||
- "State" (an _Item_ state)
|
||||
- "Event" (an openHAB event from the event bus)
|
||||
- "Command" (a command targeting an *Item*)
|
||||
- "Command" (a command targeting an _Item_)
|
||||
|
||||
And now let's have a look at the Action type.
|
||||
|
||||
|
@ -228,7 +228,7 @@ You will learn an easier way in a moment for statically defined module types
|
|||
|
||||
### Module types via json
|
||||
|
||||
In the last section we learned about the programmatic way of exposing *Module Types*.
|
||||
In the last section we learned about the programmatic way of exposing _Module Types_.
|
||||
It is actually way easier to just descripe your module types in a declarative way via json and bundle them with your addon.
|
||||
|
||||
To describe your modules (triggers, conditions, actions), add json files to `src/main/resources/OH-INF/automation/moduletypes/`.
|
||||
|
@ -338,7 +338,7 @@ The pieces of code that actually
|
|||
- decide on condition satisfaction for Condition types or
|
||||
- execute something in case of Action types
|
||||
|
||||
are called *Module handlers*.
|
||||
are called _Module handlers_.
|
||||
|
||||
We now go over the implementation for all of our custom modules.
|
||||
|
||||
|
@ -388,7 +388,7 @@ In the next three sections we'll implement those three handlers.
|
|||
|
||||
### Trigger Handler
|
||||
|
||||
A *Trigger Handler* is created by the automation engine for each trigger module type in actual rules,
|
||||
A _Trigger Handler_ is created by the automation engine for each trigger module type in actual rules,
|
||||
via the factory that we have implemented above.
|
||||
|
||||
The handler tells the rule engine that something happened.
|
||||
|
|
|
@ -5,10 +5,10 @@ title: Configuration Admin
|
|||
|
||||
# Configuration Admin Service
|
||||
|
||||
As defined in the [OSGi Compendium Release 7][OSGi-cmpn] *configuration is the process of defining the configuration data of bundles and assuring that those bundles receive that data when they are active in the OSGi Service Platform.*
|
||||
As defined in the [OSGi Compendium Release 7][OSGi-cmpn] _configuration is the process of defining the configuration data of bundles and assuring that those bundles receive that data when they are active in the OSGi Service Platform._
|
||||
|
||||
In OSGi, configurations are stored in a central database that is being managed by a special service - the *Configuration Admin Service*(`org.osgi.service.cm.ConfigurationAdmin`).
|
||||
This service monitors the service registry and **provides a configuration to the services** that are registered with a *service.pid* property.
|
||||
In OSGi, configurations are stored in a central database that is being managed by a special service - the _Configuration Admin Service_(`org.osgi.service.cm.ConfigurationAdmin`).
|
||||
This service monitors the service registry and **provides a configuration to the services** that are registered with a _service.pid_ property.
|
||||
Configuration changes are first made persistent, and then are passed to the target service.
|
||||
It is important to understand that **the target bundle receives updates from the Configuration Admin service**.
|
||||
Implementations should be aware that the update reception could be delayed if the Configuration Admin service is missing.
|
||||
|
|
|
@ -80,13 +80,13 @@ Some of the basic OSGi commands are:
|
|||
|
||||
| Command | Description |
|
||||
|-----------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| *help* | Basic command that will list all available commands |
|
||||
| *install* [bundle URL] | Installs the bundle from the given URL |
|
||||
| *start* [bundle # or bundle name] | Starts the bundle with the given numeric or symbolic id |
|
||||
| *stop* [bundle # or bundle name] | Stops the bundle with the given numeric or symbolic id |
|
||||
| *ss* | Reports a summary status of all installed bundles |
|
||||
| *diag* [bundle # or bundle name] | Reports any resolution problems for the bundle with the given numeric or symbolic id |
|
||||
| *services* [filter] | Lists all available services or only services matching to [LDAP-style filter](http://www.ldapexplorer.com/en/manual/109010000-ldap-filter-syntax.htm) (e.g. services (objectClass="\*virtage\*") - will print only services having *virtage* in their class name) |
|
||||
| _help_ | Basic command that will list all available commands |
|
||||
| _install_ [bundle URL] | Installs the bundle from the given URL |
|
||||
| _start_ [bundle # or bundle name] | Starts the bundle with the given numeric or symbolic id |
|
||||
| _stop_ [bundle # or bundle name] | Stops the bundle with the given numeric or symbolic id |
|
||||
| _ss_ | Reports a summary status of all installed bundles |
|
||||
| _diag_ [bundle # or bundle name] | Reports any resolution problems for the bundle with the given numeric or symbolic id |
|
||||
| _services_ [filter] | Lists all available services or only services matching to [LDAP-style filter](http://www.ldapexplorer.com/en/manual/109010000-ldap-filter-syntax.htm) (e.g. services (objectClass="\*virtage\*") - will print only services having _virtage_ in their class name) |
|
||||
|
||||
Table 1. Equinox commands (Source: <https://www.eclipse.org/equinox/documents/quickstart-framework.php>)
|
||||
|
||||
|
@ -130,9 +130,3 @@ Table 2. OSGi Bundles (Full list can be found at: <https://www.eclipse.org/equin
|
|||
[Equinox-repo]: https://git.eclipse.org/c/equinox/
|
||||
[Eclipse]: https://eclipse.org/eclipse/
|
||||
[Equinox-Bundles]: https://www.eclipse.org/equinox/bundles/
|
||||
[Equinox-Incubator]: https://www.eclipse.org/equinox/incubator/
|
||||
[p2]: https://www.eclipse.org/equinox/p2/
|
||||
[Equinox-Server]: https://www.eclipse.org/equinox/incubator/server/
|
||||
[products]: https://help.eclipse.org/mars/index.jsp?topic=%2Forg.eclipse.platform.doc.isv%2Fguide%2Fproduct_def.htm
|
||||
[plugins]: https://help.eclipse.org/mars/index.jsp?topic=%2Forg.eclipse.platform.doc.isv%2Fguide%2Fproduct_def_plugins.htm&cp=2_0_21_2
|
||||
[features]: https://help.eclipse.org/mars/index.jsp?topic=%2Forg.eclipse.platform.doc.isv%2Fguide%2Fproduct_def_feature.htm&cp=2_0_21_1
|
||||
|
|
|
@ -11,15 +11,15 @@ A lot of core services share information using events, so understanding how to u
|
|||
OSGi events are based on the publish-subscribe messaging pattern.
|
||||
Let's use the definition for the pattern that can be found in the [OSGi Compendium Release 7][OSGi-cmpn]:
|
||||
|
||||
*This pattern decouples sources from their handlers by interposing an event channel between them.
|
||||
The publisher posts events to the channel, which identifies which handlers need to be notified and then takes care of the notification process.*
|
||||
_This pattern decouples sources from their handlers by interposing an event channel between them.
|
||||
The publisher posts events to the channel, which identifies which handlers need to be notified and then takes care of the notification process._
|
||||
|
||||
Both publishers and subscribers can disappear at any time.
|
||||
A central module to track the handlers availability is needed - the *Event Admin Service*.
|
||||
A central module to track the handlers availability is needed - the _Event Admin Service_.
|
||||
|
||||
## Event Admin Service
|
||||
|
||||
The *Event Admin Service* (`org.osgi.service.event.EventAdmin`) takes a central place in the communication between *Event Publishers* and subscribers (*Event Listeners*).
|
||||
The _Event Admin Service_ (`org.osgi.service.event.EventAdmin`) takes a central place in the communication between _Event Publishers_ and subscribers (_Event Listeners_).
|
||||
It is responsible for keeping track of the listeners, and sending events to them.
|
||||
It supports both synchronous and asynchronous sending that will be reviewed in more details in the [section about sending events](#send-events).
|
||||
But let's illustrate that with the following picture:
|
||||
|
@ -32,15 +32,15 @@ Before going into more details, let's take a look at the events.
|
|||
|
||||
## Event
|
||||
|
||||
The *Event* interface(`org.osgi.service.event.Event`) encapsulates a single message. It contains:
|
||||
The _Event_ interface(`org.osgi.service.event.Event`) encapsulates a single message. It contains:
|
||||
|
||||
- topic - used from the *Event Admin Service* as a filter to dispatch the events only to the listeners that are interested;
|
||||
- topic - used from the _Event Admin Service_ as a filter to dispatch the events only to the listeners that are interested;
|
||||
- payload - the information that we would like to send. It is represented by a key-value pair.
|
||||
|
||||
## Receive Events
|
||||
|
||||
In order to receive an event through the *Event Admin Service* we have to register a service that implements the `org.osgi.service.event.EventHandler` interface.
|
||||
A property *event.topics* must be defined that contains all topics that we are interested in.
|
||||
In order to receive an event through the _Event Admin Service_ we have to register a service that implements the `org.osgi.service.event.EventHandler` interface.
|
||||
A property _event.topics_ must be defined that contains all topics that we are interested in.
|
||||
|
||||
```java
|
||||
package com.example.handler;
|
||||
|
@ -67,7 +67,7 @@ public class LogEventHandler implements EventHandler {
|
|||
|
||||
## Send Events
|
||||
|
||||
As we have already mentioned, you will need an *Event Admin Service* implementation to send events.
|
||||
As we have already mentioned, you will need an _Event Admin Service_ implementation to send events.
|
||||
In Equinox the service is implemented in the `org.eclipse.equinox.event` bundle.
|
||||
The service contains two methods for sending events:
|
||||
|
||||
|
|
|
@ -17,15 +17,15 @@ This page is aimed to help developers, that are going to use OSGi for the first
|
|||
|
||||
## Concepts
|
||||
|
||||
As described in the [OSGi architecture page][OSGi-architecture], *OSGi is a set of [specifications](https://docs.osgi.org/specification/) that define a dynamic component system for Java. These specifications enable a development model, where applications are dynamically composed of many different reusable components.
|
||||
The OSGi specifications enable components to hide their implementations from other components while communicating through services, which are objects that are specifically shared between components*.
|
||||
As described in the [OSGi architecture page][OSGi-architecture], _OSGi is a set of [specifications](https://docs.osgi.org/specification/) that define a dynamic component system for Java. These specifications enable a development model, where applications are dynamically composed of many different reusable components.
|
||||
The OSGi specifications enable components to hide their implementations from other components while communicating through services, which are objects that are specifically shared between components_.
|
||||
This architecture significantly reduces the overall complexity of building, maintaining and deploying applications.
|
||||
|
||||
Key features of OSGi are:
|
||||
|
||||
- **Modularity** - it is realized with the [*bundle*](#important-definitions) concept;
|
||||
- **Modularity** - it is realized with the [_bundle_](#important-definitions) concept;
|
||||
- **Runtime Dynamics** - software components can be managed at runtime;
|
||||
- **Service Orientation** - components communicate between each other through [*services*](#important-definitions).
|
||||
- **Service Orientation** - components communicate between each other through [_services_](#important-definitions).
|
||||
|
||||
## Layering
|
||||
|
||||
|
@ -48,14 +48,14 @@ Modules (called **bundles**) are the smallest unit of modularization.
|
|||
Technically a bundle is a JAR file with additional meta information.
|
||||
This information is stored in file called [**manifest**](#important-definitions) file.
|
||||
The manifest file is part of the standard [JAR specification](https://docs.oracle.com/en/java/javase/11/docs/specs/jar/jar.html#jar-manifest), but OSGi adds additional metadata to it in form of specific headers.
|
||||
The *Bundle-SymbolicName* and the *Bundle-Version* headers uniquely identify a bundle.
|
||||
The _Bundle-SymbolicName_ and the _Bundle-Version_ headers uniquely identify a bundle.
|
||||
In OSGi is allowed to have **bundles with same name, but different version running at the same time.**
|
||||
|
||||
Some of the most important information that the manifest contains are the bundle dependencies.
|
||||
**A bundle can depend on another bundle or on a package**.
|
||||
|
||||
The **OSGi runtime uses the information about the dependencies to *wire* the bundles and hides everything in this JAR unless it is explicitly exported**.
|
||||
The dependencies to the Java standard libraries are managed by the *Bundle-RequiredExecutionEnvironment* header, so it is not needed to import the Java core packages.
|
||||
The **OSGi runtime uses the information about the dependencies to _wire_ the bundles and hides everything in this JAR unless it is explicitly exported**.
|
||||
The dependencies to the Java standard libraries are managed by the _Bundle-RequiredExecutionEnvironment_ header, so it is not needed to import the Java core packages.
|
||||
|
||||
A simple manifest file can have the following content:
|
||||
|
||||
|
@ -70,7 +70,7 @@ Import-Package: org.example.required
|
|||
Export-Package: org.example.provided
|
||||
```
|
||||
|
||||
[OSGi Core Release 7, Chapter 3: Module Layer][OSGi-core] contains detailed information about the *Module Layer* and description of the headers (*Manifest-Version*, *Bundle-ManifestVersion*, *Bundle-Name*) used in this example.
|
||||
[OSGi Core Release 7, Chapter 3: Module Layer][OSGi-core] contains detailed information about the _Module Layer_ and description of the headers (_Manifest-Version_, _Bundle-ManifestVersion_, _Bundle-Name_) used in this example.
|
||||
|
||||
Bundles are used often to register and consume services.
|
||||
You will find more information about that in the [Services](#services) section.
|
||||
|
@ -78,9 +78,9 @@ You will find more information about that in the [Services](#services) section.
|
|||
## Lifecycle
|
||||
|
||||
OSGi is a dynamic platform.
|
||||
That means that bundles may be *installed, uninstalled, started, stopped or updated* at runtime (See Table 1).
|
||||
That means that bundles may be _installed, uninstalled, started, stopped or updated_ at runtime (See Table 1).
|
||||
The OSGi specification defines a mechanism how to manage the dependencies between the bundles and the functionality that they provide.
|
||||
This is achieved with the help of the *lifecycle* concept.
|
||||
This is achieved with the help of the _lifecycle_ concept.
|
||||
|
||||
The framework introduces a different states, transitions between these states and rules how this states are affecting the packages exported by the bundle and the services, that it provides.
|
||||
The table below shows the possible states of an OSGi bundle with a short explanation:
|
||||
|
@ -103,9 +103,9 @@ Fig.2 Bundle State diagram
|
|||
|
||||
## Services
|
||||
|
||||
Another main concept, that allows the bundles to communicate between each other, is the *service* model.
|
||||
Another main concept, that allows the bundles to communicate between each other, is the _service_ model.
|
||||
|
||||
**In OSGi, a bundle can register a *service* in a central [service registry](#important-definitions) under one ore more *service interface***.
|
||||
**In OSGi, a bundle can register a _service_ in a central [service registry](#important-definitions) under one ore more _service interface_**.
|
||||
It is an important feature of OSGi, because it provides a central place to register and get services.
|
||||
A bundle is permitted to register service objects at any time during the STARTING, ACTIVE or STOPPING states.
|
||||
Other bundles can go the registry and list all objects, that are registered under a specific interface or class.
|
||||
|
@ -123,8 +123,8 @@ Some important core services are presented below.
|
|||
|
||||
### Configuration Admin Service
|
||||
|
||||
In OSGi, configurations are stored in a central database that is being managed by a special service - the *Configuration Admin Service*(`org.osgi.service.cm.ConfigurationAdmin`).
|
||||
This service monitors the service registry and **provides a configuration to the services** that are registered with a *service.pid* property.
|
||||
In OSGi, configurations are stored in a central database that is being managed by a special service - the _Configuration Admin Service_(`org.osgi.service.cm.ConfigurationAdmin`).
|
||||
This service monitors the service registry and **provides a configuration to the services** that are registered with a _service.pid_ property.
|
||||
Configuration changes are first made persistent, and then are passed to the target service.
|
||||
It is important to understand that **the target bundle receives updates from the Configuration Admin service**. Implementations should be aware that the update reception could be delayed if the Configuration Admin service is missing.
|
||||
|
||||
|
@ -135,7 +135,7 @@ It is important to understand that **the target bundle receives updates from the
|
|||
In a dynamic environment like OSGi, communication with events has a wide variety of use cases.
|
||||
OSGi events are based on the publish-subscribe messaging pattern.
|
||||
|
||||
The *Event Admin Service* (`org.osgi.service.event.EventAdmin`) takes a central place in the communication between *Event Publishers* and subscribers (*Event Listeners*).
|
||||
The _Event Admin Service_ (`org.osgi.service.event.EventAdmin`) takes a central place in the communication between _Event Publishers_ and subscribers (_Event Listeners_).
|
||||
It is responsible for keeping track of the listeners, and sending events to them.
|
||||
|
||||
- [OSGi Event Admin](eventadmin.html)
|
||||
|
|
|
@ -9,7 +9,7 @@ title: OSGi Declarative Services
|
|||
|
||||
In the [OSGi Overview article](osgi.html) we have mentioned that a bundle can register, unregister, get and unget services from a central point - the Service Registry.
|
||||
|
||||
In order to simplify the usage of services the [OSGi Alliance](https://www.osgi.org/about-us/) has developed a model of managing services dynamically called *Declarative Services*.
|
||||
In order to simplify the usage of services the [OSGi Alliance](https://www.osgi.org/about-us/) has developed a model of managing services dynamically called _Declarative Services_.
|
||||
|
||||
{::options toc_levels="2"/}
|
||||
|
||||
|
@ -21,7 +21,7 @@ In order to simplify the usage of services the [OSGi Alliance](https://www.osgi.
|
|||
|
||||
In order to understand this model, we will have to first explain a few terms, used below:
|
||||
|
||||
- **Declarative Services Container** (we will use the shorthand **DS**) - a module that is managing the [lifecycle](#vii-component-lifecycle) of a *service component- dynamically.
|
||||
- **Declarative Services Container** (we will use the shorthand **DS**) - a module that is managing the [lifecycle](#component-lifecycle) of a *service component- dynamically.
|
||||
It activates and deactivates different components, basing its decisions on the information contained in the _component description_;
|
||||
- **Service Component** (or also **component**) - an object whose lifecycle is managed,
|
||||
usually by a component framework such as Declarative Services (DS).
|
||||
|
@ -36,13 +36,13 @@ In order to use the Declarative Services functionality you have to start a bundl
|
|||
In [Equinox](https://www.eclipse.org/equinox/) (the reference implementation of OSGi that is used in openHAB) this bundle is called `org.eclipse.equinox.ds`.
|
||||
|
||||
When a bundle that contains a component is added to the framework, DS reads its component description (the XML file that is generated by the Java annotations).
|
||||
If the conditions, described in this file are fulfilled (you will understand more about this in the next chapters), the DS activates the component (more on the that in the [component lifecycle](#vii-component-lifecycle) chapter).
|
||||
If the conditions, described in this file are fulfilled (you will understand more about this in the next chapters), the DS activates the component (more on the that in the [component lifecycle](#component-lifecycle) chapter).
|
||||
More importantly, after some of the requirements are not met anymore, the DS container deactivates the component.
|
||||
This ensures that service components are managed dynamically.
|
||||
|
||||
## Components
|
||||
|
||||
It is important to understand the difference between a *component** and a *service*.
|
||||
It is important to understand the difference between a _component_* and a _service_.
|
||||
A component is a normal Java class, that can reference services and provide services.
|
||||
What makes a component specific is that it is declared in a XML file and is managed completely by DS.
|
||||
That means that DS instantiates the component, calls method on this component and manages the lifecycle of a component.
|
||||
|
@ -163,7 +163,7 @@ public class MyService {
|
|||
|
||||
### Example - Provide a Service
|
||||
|
||||
Very often you will have to register a service, that implements an interface defined in the framework (e.g [*EventHandler*](https://osgi.org/javadoc/osgi.cmpn/7.0.0/org/osgi/service/event/EventHandler.html)) or interface, that you have defined.
|
||||
Very often you will have to register a service, that implements an interface defined in the framework (e.g [_EventHandler_](https://osgi.org/javadoc/osgi.cmpn/7.0.0/org/osgi/service/event/EventHandler.html)) or interface, that you have defined.
|
||||
An interface allows you to change the implementation easily or register multiple implementations in the Service Registry.
|
||||
|
||||
We will use DS to register an implementation of the EventHandler service in the OSGi Service Registry.
|
||||
|
@ -198,7 +198,7 @@ In this case we tell tell Event Admin Service in which topics we are interested.
|
|||
A component lifecycle depends of the type of the component.
|
||||
Three type of components are defined:
|
||||
|
||||
- **immediate** - with ```immediate``` attribute set to ```true``` - see the [example component description](#service-component-description);
|
||||
- **immediate** - with ```immediate``` attribute set to ```true``` - see the [example component description](#example---provide-a-service);
|
||||
- **delayed** - with ```immediate``` attribute set to ```false```;
|
||||
- **factory** - we will not discuss the lifecycle of this type in this article.
|
||||
|
||||
|
@ -233,8 +233,8 @@ The component **configuration is satisfied** when:
|
|||
- component is **enabled**;
|
||||
- all the **component references are satisfied**.
|
||||
A reference is satisfied when the reference specifies optional cardinality or there is at least one target service for the reference.
|
||||
If the component has lazy initialization (the component is *delayed*), it is moved to the REGISTERED state and it is waiting to be activated, when the service is requested (see Fig.2).
|
||||
Otherwise (the component is *immediate*) as soon as its dependencies are satisfied, the component is activated (see Fig.1).
|
||||
If the component has lazy initialization (the component is _delayed_), it is moved to the REGISTERED state and it is waiting to be activated, when the service is requested (see Fig.2).
|
||||
Otherwise (the component is _immediate_) as soon as its dependencies are satisfied, the component is activated (see Fig.1).
|
||||
|
||||
### Activation
|
||||
|
||||
|
@ -246,7 +246,7 @@ Activation consists of following steps:
|
|||
- The method that is annotated with `@Activate` is called, if present
|
||||
|
||||
After the activation, the component is in ACTIVE state.
|
||||
From this state the component can go back to the *REGISTERED- state (or to the*UNSATISFIED- state), if the component configuration becomes unsatisfied.
|
||||
From this state the component can go back to the _REGISTERED- state (or to the_UNSATISFIED- state), if the component configuration becomes unsatisfied.
|
||||
|
||||
### Deactivation
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ If the state is too old, we need to fetch it first and this may involve network
|
|||
|
||||
A common usage case of the `ExpiringCacheAsync` cache type is in a `ThingHandler` to encapsulate one value of an internal state and attach an expire time on that value.
|
||||
|
||||
A **handleCommand** implementation with the interesting *RefreshType* could look like this:
|
||||
A **handleCommand** implementation with the interesting _RefreshType_ could look like this:
|
||||
|
||||
```java
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
|
@ -85,7 +85,7 @@ with a still very common callback based device refreshing method `doSuperImporta
|
|||
The listener is the class
|
||||
itself, which implements `DeviceStateUpdateListener`.
|
||||
We will be called back with a refreshed device state in `asyncCallbackFromDeviceStateRefresh`
|
||||
and mark the Future as *complete*.
|
||||
and mark the Future as _complete_.
|
||||
|
||||
```java
|
||||
class FetchValueFromDevice implements Supplier<CompletableFuture<double>>, DeviceStateUpdateListener {
|
||||
|
|
|
@ -202,7 +202,7 @@ Note, always review the README on [Docker Hub](https://hub.docker.com/r/openhab/
|
|||
- `--net=host` : by default Docker will place a container into its own network stack. However, openHAB requires UPnP discovery so this parameter makes the Docker container use the host's network stack.
|
||||
- `-v /etc/localtime:/etc/localtime:ro` : ties the time of the container to the host's time, read only so the container cannot change the host's time
|
||||
- `-v /etc/timezone:/etc/timezone:ro` : ties the timezone of the container to the host's time zone, read only so the container cannot change the host's time zone
|
||||
- `-v /opt/openhab/conf:/openhab/conf` : location of the conf folder for openHAB configurations (*Note:* you must create these folders on the host before running the container)
|
||||
- `-v /opt/openhab/conf:/openhab/conf` : location of the conf folder for openHAB configurations (_Note:_ you must create these folders on the host before running the container)
|
||||
- `-v /opt/openhab/userdata:/openhab/userdata` : location for logs, cache, persistence databases, etc.
|
||||
- `-v /opt/openhab/addons:/openhab/addons` : only needed if installing addons unavailable via UI or the Karaf Console
|
||||
- `-v /opt/openhab/.java:/openhab/.java` : needed by the Nest 1.x binding (and others?), location of the security token
|
||||
|
|
|
@ -16,7 +16,7 @@ Always keep this in mind when searching for help and solutions.
|
|||
## Platform Recommendations
|
||||
|
||||
1. You are **new to openHAB** and just want to give it a try?
|
||||
- Set up openHAB on your local PC or Mac in just a few steps *or*
|
||||
- Set up openHAB on your local PC or Mac in just a few steps _or_
|
||||
- use a Raspi with [openHABian](openhabian.html)
|
||||
|
||||
1. You've gained some experience and want to use openHAB to seriously control your home?
|
||||
|
@ -40,7 +40,6 @@ If in doubt, explicitly install a JVM based on OpenJDK.
|
|||
You could also [download Azul Zulu](https://www.azul.com/downloads/zulu-community/?&architecture=x86-64-bit&package=jdk#) [Installation](https://docs.azul.com/zulu/zuludocs/ZuluUserGuide/InstallingZulu/InstallationWindowsUsingZuluMSIFile.htm) instructions can be found on Azul Systems' Zulu website.
|
||||
Oracle Java is also suitable for most configurations but it's not recommended. Licensing restrictions may apply.
|
||||
|
||||
|
||||
::: warning
|
||||
Please note that versions of Java higher than 11 are not supported at the moment.
|
||||
:::
|
||||
|
@ -52,7 +51,7 @@ Please note that versions of Java higher than 11 are not supported at the moment
|
|||
| [AdoptOpenJDK](https://adoptopenjdk.net) | Open Source JDK backed by many large companies | |
|
||||
|
||||
Please download and install the **Java 11** version of the JVM.
|
||||
Note that openHAB 3 will run under Java 11, and you *can* use it with openHAB 2.X as well. But be aware that although developers are working hard to make this work, there might be problems with the oldest parts of openHAB 2.x, such as some of the v1 bindings, due to non-backward compatible changes in Java 11.
|
||||
Note that openHAB 3 will run under Java 11, and you _can_ use it with openHAB 2.X as well. But be aware that although developers are working hard to make this work, there might be problems with the oldest parts of openHAB 2.x, such as some of the v1 bindings, due to non-backward compatible changes in Java 11.
|
||||
|
||||
The **64-bit version** of the JVM is **only** recommended on platforms using a 64-bit OS and an Intel or AMD processor.
|
||||
|
||||
|
|
|
@ -78,7 +78,7 @@ sudo mv openhab.gpg /usr/share/keyrings
|
|||
sudo chmod u=rw,g=r,o=r /usr/share/keyrings/openhab.gpg
|
||||
```
|
||||
|
||||
Then, you can choose between, *Official (Stable)*, *Beta* or *Snapshot* builds:
|
||||
Then, you can choose between, _Official (Stable)_, _Beta_ or _Snapshot_ builds:
|
||||
|
||||
- **Stable Release**
|
||||
|
||||
|
@ -627,7 +627,7 @@ sudo systemctl daemon-reload
|
|||
|
||||
## Backup and Restore
|
||||
|
||||
It is recommended to make a backup of your configuration before *any* major change.
|
||||
It is recommended to make a backup of your configuration before _any_ major change.
|
||||
To make a backup of openHAB 2 or higher, you need to retain your configuration and userdata files.
|
||||
openHAB comes with scripts for storing your configuration in a zip file which is saved in `/var/lib/openhab/backups` for automatic installs and `openhab/backups` for manual installs.
|
||||
You can change the default path by setting the $OPENHAB_BACKUPS environment variable.
|
||||
|
@ -792,7 +792,7 @@ Let's activate the "openhab" user as a samba user and set his password (e.g. "ha
|
|||
sudo smbpasswd -a openhab
|
||||
```
|
||||
|
||||
Be aware, that creating and later using a specific user will ensure, that [permissions](#permissions) are honored.
|
||||
Be aware, that creating and later using a specific user will ensure, that **permissions** are honored.
|
||||
Make sure, the "openhab" user has ownership and/or write access to the openHAB configuration files.
|
||||
This can be accomplished by executing:
|
||||
|
||||
|
|
|
@ -68,13 +68,11 @@ openHAB will see these incoming requests as originating from the local loopback
|
|||
|
||||
The simplest way to get hold of such an openHAB Cloud is to register an account at [myopenHAB.org](https://www.myopenhab.org/), which is operated by the [openHAB Foundation](https://www.openhabfoundation.org/).
|
||||
|
||||
{: #nginx-reverse-proxy}
|
||||
|
||||
### Running openHAB Behind a Reverse Proxy
|
||||
|
||||
A reverse proxy simply directs client requests to the appropriate server.
|
||||
This means you can proxy connections to `http://mydomain_or_myip` to your openHAB runtime.
|
||||
You just have to **replace *mydomain_or_myip*** with either an **internal or external IP** (e.g. xx.xx.xx.xx) or a **domain** if you own one that links to the external IP of openHAB (e.g. openhab.mydomain.tld).
|
||||
You just have to **replace _mydomain_or_myip_** with either an **internal or external IP** (e.g. xx.xx.xx.xx) or a **domain** if you own one that links to the external IP of openHAB (e.g. openhab.mydomain.tld).
|
||||
|
||||
Running openHAB behind a reverse proxy allows you to access your openHAB runtime via port 80 (HTTP) and 443 (HTTPS).
|
||||
It also provides you a simple way of **protecting your server** with authentication and secure certificates.
|
||||
|
@ -83,37 +81,33 @@ The good news is that [openHABian](openhabian) already offers the possibility to
|
|||
|
||||
**Table of Content:**
|
||||
|
||||
- [Setting up NGINX](#nginx-setup)
|
||||
- [Installation](#nginx-setup-install)
|
||||
- [Basic Configuration](#nginx-setup-config)
|
||||
- [Authentication with NGINX](#nginx-auth)
|
||||
- [Creating the First User](#nginx-auth-user)
|
||||
- [Referencing the File in the NGINX Configuration](#nginx-auth-file)
|
||||
- [Adding or Removing users](#nginx-auth-users)
|
||||
- [Making Exceptions for Specific IP addresses](#nginx-satisfy)
|
||||
- [Setting up a Domain](#nginx-domain)
|
||||
- [Enabling HTTPS](#nginx-https)
|
||||
- [Using OpenSSL to Generate Self-Signed Certificates](#nginx-openssl)
|
||||
- [Adding the Certificates to Your Proxy Server](#nginx-openssl-add)
|
||||
- [Using Let's Encrypt to Generate Trusted Certificates](#nginx-letsencrypt)
|
||||
- [Setting up the NGINX Proxy Server to Handle the Certificate Generation Procedure](#nginx-letsencrypt-generation)
|
||||
- [Using Certbot](#nginx-letsencrypt-certbot)
|
||||
- [Adding the Certificates to Your Proxy Server](#nginx-letsencrypt-add)
|
||||
- [Setting Your NGINX Server to Listen to the HTTPS Port](#nginx-https-listen)
|
||||
- [Redirecting HTTP Traffic to HTTPS](#nginx-httpredirect)
|
||||
- [Putting it All Together](#nginx-summary)
|
||||
- [Additional HTTPS Security](#nginx-https-security)
|
||||
- [Configuration on Synology DiskStation](#synology-remote-config)
|
||||
- [Further Reading](#nginx-further-reading)
|
||||
|
||||
{: #nginx-setup}
|
||||
- [Setting up NGINX](#setting-up-nginx)
|
||||
- [Installation](#installation)
|
||||
- [Basic Configuration](#basic-configuration)
|
||||
- [Authentication with NGINX](#authentication-with-nginx)
|
||||
- [Creating the First User](#creating-the-first-user)
|
||||
- [Referencing the File in the NGINX Configuration](#referencing-the-file-in-the-nginx-configuration)
|
||||
- [Adding or Removing users](#adding-or-removing-users)
|
||||
- [Making Exceptions for Specific IP addresses](#making-exceptions-for-specific-ip-addresses)
|
||||
- [Setting up a Domain](#setting-up-a-domain)
|
||||
- [Enabling HTTPS](#enabling-https)
|
||||
- [Using OpenSSL to Generate Self-Signed Certificates](#using-openssl-to-generate-self-signed-certificates)
|
||||
- [Adding the Certificates to Your Proxy Server](#adding-the-certificates-to-your-proxy-server)
|
||||
- [Using Let's Encrypt to Generate Trusted Certificates](#using-lets-encrypt-to-generate-trusted-certificates)
|
||||
- [Setting up the NGINX Proxy Server to Handle the Certificate Generation Procedure](#setting-up-the-nginx-proxy-server-to-handle-the-certificate-generation-procedure)
|
||||
- [Using Certbot](#using-certbot)
|
||||
- [Adding the Certificates to Your Proxy Server](#adding-the-certificates-to-your-proxy-server-1)
|
||||
- [Setting Your NGINX Server to Listen to the HTTPS Port](#setting-your-nginx-server-to-listen-to-the-https-port)
|
||||
- [Redirecting HTTP Traffic to HTTPS](#redirecting-http-traffic-to-https)
|
||||
- [Putting it All Together](#putting-it-all-together)
|
||||
- [Additional HTTPS Security](#additional-https-security)
|
||||
- [Configuration on Synology DiskStation](#configuration-on-synology-diskstation)
|
||||
- [Further Reading](#further-reading)
|
||||
|
||||
#### Setting up NGINX
|
||||
|
||||
These are the steps required to use [**NGINX**](https://nginx.org), a lightweight HTTP server, although you can use **Apache HTTP** server or any other HTTP server which supports reverse proxying.
|
||||
|
||||
{: #nginx-setup-install}
|
||||
|
||||
##### Installation
|
||||
|
||||
NGINX runs as a service in most Linux distributions, installation should be as simple as:
|
||||
|
@ -125,8 +119,6 @@ sudo apt-get update && sudo apt-get install nginx
|
|||
Once installed, you can test to see if the service is running correctly by going to `http://mydomain_or_myip`, you should see the default "Welcome to nginx" page.
|
||||
If you don't, you may need to check your firewall or ports and check if port 80 (and 443 for HTTPS later) is not blocked and that services can use it.
|
||||
|
||||
{: #nginx-setup-config}
|
||||
|
||||
##### Basic Configuration
|
||||
|
||||
NGINX configures the server when it starts up based on configuration files.
|
||||
|
@ -179,24 +171,20 @@ sudo service nginx restart
|
|||
|
||||
...and then go to `http://mydomain_or_myip` to see your openHAB server.
|
||||
|
||||
{: #nginx-auth}
|
||||
|
||||
#### Authentication with NGINX
|
||||
|
||||
For further security, you may wish to ask for a **username and password** before users have access to openHAB.
|
||||
This is fairly simple in NGINX once you have the reverse proxy setup, you just need to provide the server with a basic authentication user file.
|
||||
|
||||
{: #nginx-auth-user}
|
||||
|
||||
##### Creating the First User
|
||||
|
||||
You will be using *htpasswd* to generate a username/password file, this utility can be found in the apache2-utils package:
|
||||
You will be using _htpasswd_ to generate a username/password file, this utility can be found in the apache2-utils package:
|
||||
|
||||
```shell
|
||||
sudo apt-get install apache2-utils
|
||||
```
|
||||
|
||||
To generate a file that NGINX can use you use the following command, don't forget to change *username* to something meaningful!
|
||||
To generate a file that NGINX can use you use the following command, don't forget to change _username_ to something meaningful!
|
||||
|
||||
```shell
|
||||
sudo htpasswd -c /etc/nginx/.htpasswd username
|
||||
|
@ -205,8 +193,6 @@ sudo htpasswd -c /etc/nginx/.htpasswd username
|
|||
You will receive a prompt to create a password for this username, once finished the file will be created.
|
||||
You're then free to reference the file to NGINX.
|
||||
|
||||
{: #nginx-auth-file}
|
||||
|
||||
##### Referencing the File in the NGINX Configuration
|
||||
|
||||
Now the configuration file (`/etc/nginx/sites-enabled/openhab`) needs to be edited to use this password.
|
||||
|
@ -229,8 +215,6 @@ This is not required prior to openHAB 3.0. You must add the following two direct
|
|||
|
||||
Once done, **test and restart your NGINX service** and authentication should now be enabled on your server!
|
||||
|
||||
{: #nginx-auth-users}
|
||||
|
||||
##### Adding or Removing users
|
||||
|
||||
To add new users to your site, you must use following command, **do not** use the `-c` modifier again as this will remove all previously created users:
|
||||
|
@ -247,8 +231,6 @@ sudo htpasswd -D /etc/nginx/.htpasswd username
|
|||
|
||||
Once again, any changes you make to these files **must be followed with restarting the NGINX service** otherwise no changes will be made.
|
||||
|
||||
{: #nginx-satisfy}
|
||||
|
||||
#### Making Exceptions for Specific IP addresses
|
||||
|
||||
It is often desirable to allow specific IPs (e.g. the local network) to access openHAB without needing to prompt for a password or to block everyone else entirely.
|
||||
|
@ -265,29 +247,23 @@ These lines are placed in the `location{}` block. For example, by adding the lin
|
|||
NGINX will allow anyone within the 192.168.0.0/24 range **and** the localhost to connect without a password.
|
||||
If you have setup a password following the previous section, then the rest will be prompted for a password for access.
|
||||
|
||||
{: #nginx-domain}
|
||||
|
||||
#### Setting up a Domain
|
||||
|
||||
To generate a trusted certificate, you need to own a domain. To acquire your own domain, you can use one of the following methods:
|
||||
|
||||
| Method | Example Links | Note |
|
||||
|:-------------------------------- |:------------- |:---- |
|
||||
| Purchasing a domain name | [GoDaddy](https://www.godaddy.com), [Namecheap](https://www.namecheap.com), [Enom](https://www.enom.com), [Register](https://www.register.com) | You should have an IP adress that doesn't change (i.e. fixed), or changes rarely, and then update the DNS *A record* so that your domain/subdomain to point towards your IP. |
|
||||
| Purchasing a domain name | [GoDaddy](https://www.godaddy.com), [Namecheap](https://www.namecheap.com), [Enom](https://www.enom.com), [Register](https://www.register.com) | You should have an IP adress that doesn't change (i.e. fixed), or changes rarely, and then update the DNS _A record_ so that your domain/subdomain to point towards your IP. |
|
||||
| Obtaining a free domain | [FreeNom](https://www.freenom.com) | Setup is the same as above. |
|
||||
| Using a "Dynamic DNS" sevice | [No-IP](https://www.noip.com), [Dyn](https://www.dyn.com/dns), [FreeDNS](https://freedns.afraid.org) | Uses a client to automatically update your IP to a domain of you choice, some Dynamic DNS services (like FreeDNS) offer a free domain too. |
|
||||
|
||||
{: #nginx-https}
|
||||
|
||||
#### Enabling HTTPS
|
||||
|
||||
Encrypting the communication between client and the server is important because it protects against eavesdropping and possible forgery.
|
||||
The following options are available depending if you have a valid domain:
|
||||
|
||||
If you have a **valid domain and can change the DNS** to point towards your IP, follow the [instructions for Let's Encrypt](#nginx-letsencrypt)
|
||||
If you need to use an internal or external IP to connect to openHAB, follow the [instructions for OpenSSL](#nginx-openssl)
|
||||
|
||||
{: #nginx-openssl}
|
||||
If you have a **valid domain and can change the DNS** to point towards your IP, follow the [instructions for Let's Encrypt](#using-lets-encrypt-to-generate-trusted-certificates)
|
||||
If you need to use an internal or external IP to connect to openHAB, follow the [instructions for OpenSSL](#using-openssl-to-generate-self-signed-certificates)
|
||||
|
||||
#### Using OpenSSL to Generate Self-Signed Certificates
|
||||
|
||||
|
@ -312,8 +288,6 @@ sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/openha
|
|||
You will be prompted for some information which you will need to fill out for the certificate, when it asks for a **Common Name**, you may enter your IP Address:
|
||||
Common Name (e.g. server FQDN or YOUR name) []: xx.xx.xx.xx
|
||||
|
||||
{: #nginx-openssl-add}
|
||||
|
||||
##### Adding the Certificates to Your Proxy Server
|
||||
|
||||
The certificate and key should have been placed in `/etc/ssl/`.
|
||||
|
@ -325,8 +299,6 @@ In the NGINX configuration, place the following underneath your `server_name` va
|
|||
ssl_certificate_key /etc/ssl/openhab.key;
|
||||
```
|
||||
|
||||
{: #nginx-letsencrypt}
|
||||
|
||||
#### Using Let's Encrypt to Generate Trusted Certificates
|
||||
|
||||
::: tip
|
||||
|
@ -335,12 +307,10 @@ Skip this step if you have no domain name or have already followed the instructi
|
|||
|
||||
Let's Encrypt is a service that allows anyone with a valid domain to automatically generate a trusted certificate, these certificates are usually accepted by a browser without any warnings.
|
||||
|
||||
{: #nginx-letsencrypt-generation}
|
||||
|
||||
##### Setting up the NGINX Proxy Server to Handle the Certificate Generation Procedure
|
||||
|
||||
Let's Encrypt needs to validate that the server has control of the domain.
|
||||
The simplest way of doing this is using a **webroot plugin** to place a file on the server, and then access it using a specific url: */.well-known/acme-challenge*.
|
||||
The simplest way of doing this is using a **webroot plugin** to place a file on the server, and then access it using a specific url: _/.well-known/acme-challenge_.
|
||||
Since the proxy only forwards traffic to the openHAB server, the server needs to be told to handle requests at this address differently.
|
||||
|
||||
First, **create a directory** that Certbot can be given access to:
|
||||
|
@ -357,8 +327,6 @@ Next add the new location parameter to your NGINX config, this should be **place
|
|||
}
|
||||
```
|
||||
|
||||
{: #nginx-letsencrypt-certbot}
|
||||
|
||||
##### Using Certbot
|
||||
|
||||
Certbot is a tool which simplifies the process of obtaining secure certificates.
|
||||
|
@ -369,8 +337,6 @@ Don't forget to change the example domain to your own! An example of a valid cer
|
|||
sudo certbot certonly --webroot -w /var/www/mydomain -d mydomain
|
||||
```
|
||||
|
||||
{: #nginx-letsencrypt-add}
|
||||
|
||||
##### Adding the Certificates to Your Proxy Server
|
||||
|
||||
The certificate and key should have been placed in `/etc/letsencrypt/live/mydomain_or_myip`.
|
||||
|
@ -383,8 +349,6 @@ In the NGINX configuration, place the following underneath your server_name vari
|
|||
add_header Strict-Transport-Security "max-age=31536000";
|
||||
```
|
||||
|
||||
{: #nginx-https-listen}
|
||||
|
||||
#### Setting Your NGINX Server to Listen to the HTTPS Port
|
||||
|
||||
Regardless of the option you choose, make sure you change the port to listen in on HTTPS traffic.
|
||||
|
@ -398,8 +362,6 @@ You can check by going to `https://mydomain_or_myip` and confirming with your br
|
|||
**These certificates expire within a few months** so it is important to run the updater in a cron expression (and also restart NGINX) as explained in the Certbot setup instructions.
|
||||
If you want to keep hold of a HTTP server for some reason, just add `listen 80;` and remove the Strict-Transport-Security line.
|
||||
|
||||
{: #nginx-httpredirect}
|
||||
|
||||
#### Redirecting HTTP Traffic to HTTPS
|
||||
|
||||
You may want to redirect all HTTP traffic to HTTPS, you can do this by adding the following to the NGINX configuration.
|
||||
|
@ -424,11 +386,9 @@ server {
|
|||
}
|
||||
```
|
||||
|
||||
{: #nginx-summary}
|
||||
|
||||
#### Putting it All Together
|
||||
|
||||
After following all the steps on this page, you *should* have a NGINX server configuration (`/etc/nginx/sites-enabled/openhab`) that looks like this:
|
||||
After following all the steps on this page, you _should_ have a NGINX server configuration (`/etc/nginx/sites-enabled/openhab`) that looks like this:
|
||||
|
||||
```nginx
|
||||
server {
|
||||
|
@ -477,8 +437,6 @@ server {
|
|||
}
|
||||
```
|
||||
|
||||
{: #synology-remote-config}
|
||||
|
||||
#### Configuration on Synology DiskStation
|
||||
|
||||
Synology DSM (as of 6.2) has the ability to automatically acquire certificates from Let's Encrypt and renew them every 90 days as required.
|
||||
|
@ -487,7 +445,7 @@ The majority of the configuration mentioned above can be completed through the D
|
|||
Before you continue, make sure you have the below conditions:
|
||||
|
||||
- A working installation of openHAB on your DiskStation (see the [Synology Installation Guide](https://www.openhab.org/docs/installation/synology.html/))
|
||||
- Your own domain you can configure the CAA record for (see [Setting up a Domain](#nginx-domain))
|
||||
- Your own domain you can configure the CAA record for (see [Setting up a Domain](#setting-up-a-domain))
|
||||
- Access to your DiskStation by SSH ([How to login to DSM with root permission via SSH/Telnet](https://www.synology.com/en-global/knowledgebase/DSM/tutorial/General_Setup/How_to_login_to_DSM_with_root_permission_via_SSH_Telnet/))
|
||||
- Ports 80 and 443 forwarded from your router to your DiskStation (make sure you reconfigure the router web UI to a different port first, so you don't lose access!)
|
||||
|
||||
|
@ -649,13 +607,11 @@ sudo tail -f /var/log/nginx/error.log
|
|||
|
||||
This log will update in real-time, so do whatever it was that you were having issues with again, and you'll see the error.
|
||||
|
||||
{: #nginx-https-security}
|
||||
|
||||
#### Additional HTTPS Security
|
||||
|
||||
To test your security settings [SSL Labs](https://www.ssllabs.com/ssltest/) provides a tool for testing your domain against ideal settings (Make sure you check "Do not show the results on the boards" if you dont want your domain seen).
|
||||
|
||||
This optional section is for those who would like to strengthen the HTTPS security on openHAB, it can be applied regardless of which HTTPS method you used [above](#nginx-https), **but you need to follow at least one of them first**.
|
||||
This optional section is for those who would like to strengthen the HTTPS security on openHAB, it can be applied regardless of which HTTPS method you used [above](#enabling-https), **but you need to follow at least one of them first**.
|
||||
|
||||
First, we need to generate a stronger key exchange, to do this we can generate an additional key with OpenSSL.
|
||||
|
||||
|
@ -684,8 +640,6 @@ All of these settings are customisable, but make sure you [read up on](https://n
|
|||
Feel free to test the new configuration again on [SSL Labs](https://www.ssllabs.com/ssltest/).
|
||||
If you're achieving A or A+ here, then your client-openHAB communication is very secure.
|
||||
|
||||
{: #nginx-further-reading}
|
||||
|
||||
#### Further Reading
|
||||
|
||||
The setup above is a suggestion for high compatibility with an A+ rating at the time of writing, however flaws in these settings (particularly the cyphers) may become known overtime.
|
||||
|
|
|
@ -154,10 +154,10 @@ The filename and format of the uploaded file will be checked before installation
|
|||
If there is not a Java8 package in the Package Center, your machine may not be supported by the [Synology package](https://www.synology.com/en-us/dsm/packages/Java8).
|
||||
|
||||
The best option for older unsupported Synology models such as **PowerPC** and **ARMv5** is to include the [PC-Loadletter](https://pcloadletter.co.uk/2011/08/23/java-package-for-synology/) Repo.
|
||||
[Download Java SE](https://www.oracle.com/technetwork/java/embedded/embedded-se/downloads/index.html) [(latest ARMv6)](https://www.oracle.com/technetwork/java/embedded/embedded-se/downloads/javase-embedded-downloads-2209751.html) [(Java Cryptography Extension if required)](https://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html) and put them in the *public* folder of your NAS.
|
||||
[Download Java SE](https://www.oracle.com/technetwork/java/embedded/embedded-se/downloads/index.html) [(latest ARMv6)](https://www.oracle.com/technetwork/java/embedded/embedded-se/downloads/javase-embedded-downloads-2209751.html) [(Java Cryptography Extension if required)](https://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html) and put them in the _public_ folder of your NAS.
|
||||
Then start the installation of Java8 SE.
|
||||
|
||||
*Note that it may be necessary to rename the downloaded file to match the name the Loadletter utility expects which may be an older version than what is currently available.*
|
||||
_Note that it may be necessary to rename the downloaded file to match the name the Loadletter utility expects which may be an older version than what is currently available._
|
||||
|
||||
The **Java8 PowerPC** versions are available from [Oracle](https://www.oracle.com/technetwork/java/embedded/embedded-se/downloads/javaseembedded8u6-2406243.html).
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ By installing the openHAB process as a service in Windows, you can:
|
|||
|
||||
#### Windows Service Installation Steps
|
||||
|
||||
1. Complete the [prerequisites](#prerequisites) and regular [installation](#installation) steps.
|
||||
1. Complete the [prerequisites](#before-you-start) and regular [installation](#installation) steps.
|
||||
1. Issue the following two commands in your openHAB console:
|
||||
|
||||
```shell
|
||||
|
|
|
@ -22,7 +22,7 @@ h1.welcome {
|
|||
|
||||
<h1 class="welcome">Welcome!</h1>
|
||||
|
||||
The **open H**ome **A**utomation **B**us (openHAB, *pronounced ˈəʊpənˈhæb*) is an open source, technology agnostic home automation platform which runs as the center of your smart home!
|
||||
The **open H**ome **A**utomation **B**us (openHAB, _pronounced ˈəʊpənˈhæb_) is an open source, technology agnostic home automation platform which runs as the center of your smart home!
|
||||
|
||||
<div style="clear:both"></div>
|
||||
|
||||
|
@ -44,7 +44,7 @@ Here are some key considerations especially for new users. To be successful, you
|
|||
- Celebrate all the small successes
|
||||
|
||||
Remember, openHAB is just a computer program.
|
||||
The computer will only do what *you* tell it to do.
|
||||
The computer will only do what _you_ tell it to do.
|
||||
openHAB can provide many default solutions that are easy to setup.
|
||||
On the flip side, the more you insist that everything should look and work exactly the way you want it, the more work you will have to invest.
|
||||
openHAB is fully customizable, but doing so will require substantial effort on your part.
|
||||
|
|
|
@ -93,7 +93,6 @@ Use [openHABs console](/administration/console.html#using-the-console) or just r
|
|||
|
||||
> openhab-cli console
|
||||
|
||||
|
||||
and then enter the following command:
|
||||
|
||||
```text
|
||||
|
|
|
@ -30,7 +30,7 @@ You will have to apply the widget to an Item and refresh a page after saving the
|
|||
## Building Custom Widgets
|
||||
|
||||
As you are learning how widgets work and all of the available options, it might be easier to create the widget using the form presented when adding the Item metadata and then copying the YAML from the code tab to the Custom Widget editor.
|
||||
When doing this make sure to fill out *all* the fields, because when using the defaults no value is added to the YAML in the code tab.
|
||||
When doing this make sure to fill out _all_ the fields, because when using the defaults no value is added to the YAML in the code tab.
|
||||
So, for example, be sure to enter in the Item field.
|
||||
|
||||
Here is a filled-out form customizing a list Item widget for a light.
|
||||
|
|
|
@ -103,7 +103,7 @@ There is also a [marketplace](https://community.openhab.org/c/marketplace/69) av
|
|||
By default the state of the Item will be displayed on the right hand side of the widget.
|
||||
Sometimes the binding will provide hints on how to display the state, but most of the time this default will be just the string from `MyItem.state.toString()`.
|
||||
|
||||
Note that the `label` field of an Item's definition in a .items file or the label set on the Item is *not* used by MainUI.
|
||||
Note that the `label` field of an Item's definition in a .items file or the label set on the Item is _not_ used by MainUI.
|
||||
|
||||
To customize the state of the Item, the "State Description" metadata must be configured.
|
||||
This metadata lets you define the format and any transformations to apply to the Item's state before it is displayed.
|
||||
|
|
|
@ -69,7 +69,7 @@ The House has a Ground Floor and the Ground Floor has rooms including a Living R
|
|||
The Living Room has a Rollershutter equipment which in turn has a Control and Power point Item.
|
||||
The locations and equipment are Group Items and Control and Power are other types of Items.
|
||||
|
||||
As discussed, one is not required to *only* use the semantic model.
|
||||
As discussed, one is not required to _only_ use the semantic model.
|
||||
It is possible and encouraged to create Groups and Items that are outside of the model where necessary.
|
||||
In this example, the Rollershutter in the Living Room is a member of the `AllRollershutters` Group which could be used to determine if any are OPEN and send commands to all the rollershutters in the house at once.
|
||||
But this functional cross cutting Group is not an Equipment nor is it a Location and it violates the restrictions of the model.
|
||||
|
@ -212,22 +212,22 @@ This is a table describing the Equipment, Point and Property classes needed to e
|
|||
|
||||
| Badge | Type | Equipment | Point | Property |
|
||||
|--------------|-------------|------------------------------------------------------------|------------------------------------|-------------|
|
||||
| Low Battery | Status | *Any* | LowBattery | *Any* |
|
||||
| Lights | Status | *Any* | Control, Switch | Light |
|
||||
| Windows | Status | Window | OpenState | *Any* |
|
||||
| Doors | Status | Door, FrontDoor, BackDoor, InnerDoor, CellarDoor, SideDoor | OpenState | *Any* |
|
||||
| Garage Doors | Status | GarageDoor | OpenState | *Any* |
|
||||
| Blinds | Status | Blinds | OpenState | *Any* |
|
||||
| Presence | Status | *Any* | Status | Presence |
|
||||
| Lock | Status | Lock | Status, OpenState, Control, Switch | *Any* |
|
||||
| Climate | Status | HVAC | Status, Control, Switch | *Any* |
|
||||
| Low Battery | Status | _Any_ | LowBattery | _Any_ |
|
||||
| Lights | Status | _Any_ | Control, Switch | Light |
|
||||
| Windows | Status | Window | OpenState | _Any_ |
|
||||
| Doors | Status | Door, FrontDoor, BackDoor, InnerDoor, CellarDoor, SideDoor | OpenState | _Any_ |
|
||||
| Garage Doors | Status | GarageDoor | OpenState | _Any_ |
|
||||
| Blinds | Status | Blinds | OpenState | _Any_ |
|
||||
| Presence | Status | _Any_ | Status | Presence |
|
||||
| Lock | Status | Lock | Status, OpenState, Control, Switch | _Any_ |
|
||||
| Climate | Status | HVAC | Status, Control, Switch | _Any_ |
|
||||
| Screens | Status | Screen, Television | Status, Control, Switch | Power |
|
||||
| Speakers | Status | Receiver, Speaker | Status, Control, Switch | Power |
|
||||
| Projectors | Status | Projector | Status, Control, Switch | Power |
|
||||
| Alarms | Status | *Any* | Alarm | *Any* |
|
||||
| Luminance | Measurement | *Any* | Measurement | Light |
|
||||
| Temperature | Measurement | *Any* | Measurement | Temperature |
|
||||
| Humidity | Measurement | *Any* | Measurement | Humidity |
|
||||
| Alarms | Status | _Any_ | Alarm | _Any_ |
|
||||
| Luminance | Measurement | _Any_ | Measurement | Light |
|
||||
| Temperature | Measurement | _Any_ | Measurement | Temperature |
|
||||
| Humidity | Measurement | _Any_ | Measurement | Humidity |
|
||||
|
||||
This table is based off the sources:
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ But the question is, when does it save those Item states?
|
|||
- Only when the Item receives a command?
|
||||
- Every minute whether it has received an event or not?
|
||||
|
||||
These are all different *persistence strategies*.
|
||||
These are all different _persistence strategies_.
|
||||
openHAB supports all of them, and they can be combined (e.g. every Item changed and every five minutes.)
|
||||
|
||||
One special persistence strategy is `restoreOnStartup` which will update the Item with the most recently saved Item state when openHAB starts up or otherwise refreshes the Item.
|
||||
|
|
|
@ -114,7 +114,7 @@ We find the Timer creation documented under [ScriptExecution](/addons/automation
|
|||
A Timer will execute a block of code passed to it as the second argument at the time specified by the first argument.
|
||||
|
||||
In JavaScript this block of code would be defined in a function.
|
||||
There are *lots* of ways to define functions in JavaScript including inline anonymous, and more.
|
||||
There are _lots_ of ways to define functions in JavaScript including inline anonymous, and more.
|
||||
See one of the many tutorials on JavaScript functions for details (e.g. search "JavaScript functions" on Google).
|
||||
I'll define a separate variable to hold the function here.
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ These are where you'll access Items, call actions, get data from persistence, cr
|
|||
The Library category is where Blockly Libraries installed from the Marketplace will appear (see below and the previous discussion on Rule Templates).
|
||||
|
||||
Some sections will be short.
|
||||
If you are missing details, see the previous section for details as most of the steps are the same for creating *all* rules in the UI.
|
||||
If you are missing details, see the previous section for details as most of the steps are the same for creating _all_ rules in the UI.
|
||||
|
||||
## Building a Rule
|
||||
|
||||
|
@ -87,7 +87,7 @@ See the previous page for details on how to create the trigger you need.
|
|||
In this example we will use an `ON` command to the `MotionSensor` Item as the signal that there is motion.
|
||||
The motion sensor will timeout for 30 seconds before reporting motion again.
|
||||
There are three options to choose from which are explained very well [here](https://www.openhab.org/docs/configuration/rules-dsl.html#manipulating-item-states).
|
||||
In simple terms "changed" means the rule only triggers if the state *has changed* for example from OFF to ON while "was updated" would even trigger the rule if "OFF" was set to an item state that was already OFF.
|
||||
In simple terms "changed" means the rule only triggers if the state _has changed_ for example from OFF to ON while "was updated" would even trigger the rule if "OFF" was set to an item state that was already OFF.
|
||||
|
||||

|
||||
|
||||
|
@ -280,7 +280,7 @@ Look in the "Text" category for operations to combine strings together for loggi
|
|||
|
||||
- Watch the logs for errors, your log statements, and relevant events (see the [Blockly Reference]({{base}}/configuration/blockly/index.html) on how to easily access log information)
|
||||
|
||||
- When asking for help on the forum, don't *just* post a screenshot of the blocks.
|
||||
- When asking for help on the forum, don't _just_ post a screenshot of the blocks.
|
||||
Also post the code the blocks generate or, even better back out of the script to the rule and post the contents of the "Code" tab which gives the helpers on the forum the full picture.
|
||||
|
||||
Note that you can even add comments to your blocks to document the intention of a block of code.
|
||||
|
|
|
@ -22,7 +22,7 @@ openHAB is an event driven system.
|
|||
What that means is an event happens and parts of openHAB that watch for that event can react.
|
||||
Persistence will see an Item change event and save that new state to the database.
|
||||
The UIs will watch for that same Item change event and update the UI widgets as necessary.
|
||||
And some rules will *trigger* when that Item change event occurs to create some behavior.
|
||||
And some rules will _trigger_ when that Item change event occurs to create some behavior.
|
||||
|
||||
For example, the behavior we want is to turn on a light (represented by the Item `Light`) when motion is detected (represented by the Item `Motion`).
|
||||
To create this behavior we could create a rule that triggers on the event of the `Motion` Item receiving the command `ON` that sends the command `ON` to the `Light` Item.
|
||||
|
|
|
@ -48,7 +48,7 @@ With that in mind, it is advisable to build the page for the narrow screens firs
|
|||
|
||||
For cells and masonry, you don't have to worry about it, it will be handled for you. However, when you choose to keep control of the layout by making use of rows and columns, you need to take extra care about the responsive breakpoints.
|
||||
|
||||
These are controlled using the parameters on the column (`oh-grid-col`) components - you can configure them in the Design tab with the *Column Options* menu entries, or in YAML with the Code tab or a "Edit YAML" options on a parent component.
|
||||
These are controlled using the parameters on the column (`oh-grid-col`) components - you can configure them in the Design tab with the _Column Options_ menu entries, or in YAML with the Code tab or a "Edit YAML" options on a parent component.
|
||||
|
||||

|
||||
|
||||
|
@ -161,8 +161,8 @@ The first thing to do when creating a Fixed Layout is to define your screen size
|
|||
|
||||
::: tip Note
|
||||
|
||||
For most modern tablets, mobile phones and some other screens the **CSS resolution** is different from the **physical pixel resolution** (sometimes referred to as *Retina* displays).
|
||||
The user interface tries to help you determining the CSS resolution by showing the currently detected value as *Current Screen* rate at the top of the virtual screen area.
|
||||
For most modern tablets, mobile phones and some other screens the **CSS resolution** is different from the **physical pixel resolution** (sometimes referred to as _Retina_ displays).
|
||||
The user interface tries to help you determining the CSS resolution by showing the currently detected value as _Current Screen_ rate at the top of the virtual screen area.
|
||||
|
||||
:::
|
||||
|
||||
|
@ -170,7 +170,7 @@ The user interface tries to help you determining the CSS resolution by showing t
|
|||
|
||||
To define your screen size open the '#' menu and click **Configure Grid Layout**.
|
||||
|
||||
The layout editor shows a gray surface as the *virtual screen area*, which represents your defined screen.
|
||||
The layout editor shows a gray surface as the _virtual screen area_, which represents your defined screen.
|
||||
You can now place widgets on that screen by clicking the **Add Widget** button.
|
||||
Just like with responsive layouts a placeholder will appear, allowing you to choose widgets from the library.
|
||||
|
||||
|
@ -189,22 +189,22 @@ The following parameters can be adjusted for a Fixed Grid Layout:
|
|||
|
||||
##### Layout Settings
|
||||
|
||||
*Number of Columns:*
|
||||
_Number of Columns:_
|
||||
Number of grid columns across the page. Defaults to 16.
|
||||
Limited to a minimum widget width of 50px (calculated from screen width, margin and number of columns)
|
||||
|
||||
*Margin:*
|
||||
_Margin:_
|
||||
Margin between items and to screen edge in CSS pixels. Defaults to 10.
|
||||
|
||||
##### Screen Settings
|
||||
|
||||
*Screen Width:*
|
||||
_Screen Width:_
|
||||
Screen width in CSS pixels. Defaults to 1280.
|
||||
|
||||
*Screen Height:*
|
||||
_Screen Height:_
|
||||
Screen width in CSS pixels. Defaults to 720.
|
||||
|
||||
*Scaling:*
|
||||
_Scaling:_
|
||||
Enabling this scales the defined screen to the width available in the browser window.
|
||||
All widgets are resized accordingly, with the margin staying fixed.
|
||||
While this works well in many cases, it can lead to unpredictable styling issues, especially on large divergence from the defined screen width.
|
||||
|
@ -212,16 +212,16 @@ Defaults to false.
|
|||
|
||||
##### Appearance
|
||||
|
||||
*Hide Navigation Bar:*
|
||||
_Hide Navigation Bar:_
|
||||
When enabled the navigation bar on top of a page does not get displayed on this page.
|
||||
In conjunction with hiding the sidebar via its pin icon, this can be used for full screen display, e.g. in a fullscreen browser or when used as Home Screen App on iOS.
|
||||
Defaults to false.
|
||||
|
||||
*Hide Sidebar Icon:*
|
||||
_Hide Sidebar Icon:_
|
||||
With the navigation bar hidden, an icon is displayed on the top left corner when the sidebar is closed.
|
||||
Enabling this hides the icon. Defaults to false.
|
||||
|
||||
*Show Fullscreen Icon:*
|
||||
_Show Fullscreen Icon:_
|
||||
Show a fullscreen icon on the top right corner to enter browser fullscreen mode.
|
||||
Defaults to false.
|
||||
|
||||
|
@ -229,7 +229,7 @@ Defaults to false.
|
|||
|
||||
To define your screen size open the canvas menu and click **Configure Canvas Layout**.
|
||||
|
||||
The layout editor shows a gray surface as the *virtual screen area*, which represents your defined screen.
|
||||
The layout editor shows a gray surface as the _virtual screen area_, which represents your defined screen.
|
||||
You can now place widgets on that screen by clicking the **Add Widget** button.
|
||||
Just like with responsive layouts a placeholder will appear, allowing you to choose widgets from the library.
|
||||
|
||||
|
@ -248,27 +248,27 @@ The following parameters can be adjusted for a Fixed Canvas Layout:
|
|||
|
||||
##### Layout Settings
|
||||
|
||||
*Grid size:*
|
||||
_Grid size:_
|
||||
Pitch of the grid when the editor grid button is enabled, in CSS pixels.
|
||||
|
||||
##### Screen Settings
|
||||
|
||||
*Screen Width:*
|
||||
_Screen Width:_
|
||||
Screen width in CSS pixels. Defaults to 1280.
|
||||
|
||||
*Screen Height:*
|
||||
_Screen Height:_
|
||||
Screen width in CSS pixels. Defaults to 720.
|
||||
|
||||
*Scaling:*
|
||||
_Scaling:_
|
||||
Enabling this scales the defined screen to the width available in the browser window. All widgets are resized accordingly.
|
||||
While this works well in many cases, it can lead to unpredictable styling issues, especially on large divergence from the defined screen width.
|
||||
Defaults to false.
|
||||
|
||||
*Image URL:*
|
||||
_Image URL:_
|
||||
URL of the image to display in the background. The image is stretched to fit the screen size, while preserving its aspect ratio.
|
||||
If you want to achieve a different placement, adding margins to the image in an image editor will be necessary.
|
||||
|
||||
*Image Source Set:*
|
||||
_Image Source Set:_
|
||||
The setting is passed to the [`srcset`](https://developer.mozilla.org/en-US/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images) attribute of the image element, allowing to specify different images to be used depending on the actual resolution of the device, for example is the layout will be used both on a so called 'retina' and non-'retina' tablet.
|
||||
|
||||
##### Widget Settings
|
||||
|
@ -278,12 +278,12 @@ It provides access to the settings related to the type of the widget (**Widget S
|
|||
|
||||
##### Container Settings
|
||||
|
||||
*Preserve classic style:*
|
||||
_Preserve classic style:_
|
||||
Enabling this option preserves the widget style definition as in other layout pages (responsive, fixed grid).
|
||||
Usually, this means preserving the background of the widget.
|
||||
|
||||
*Shadow:*
|
||||
_Shadow:_
|
||||
Applies a shadow to the widget inner outline.
|
||||
|
||||
*Bring to Front*, *Mode Up*, *Move Down*, *Send to Back*:
|
||||
_Bring to Front_, _Mode Up_, _Move Down_, _Send to Back_:
|
||||
Change the drawing order of several overlapping widgets.
|
||||
|
|
|
@ -166,7 +166,7 @@ Because of this, the `Label` component also accepts `class` and `style` configur
|
|||
`Label` components are often used extensively in compound widgets with several other components to place informative text.
|
||||
However, because of the `<div>` container, there are times and situations where the `Label` component can cause placement/alignment issues or even configuration issues if the parent element is not compatible with having a `<div>` container as a child.
|
||||
|
||||
In contrast, the `Content` component renders the value given by the `text` property *without* any additional container.
|
||||
In contrast, the `Content` component renders the value given by the `text` property _without_ any additional container.
|
||||
For example:
|
||||
|
||||
```yaml
|
||||
|
|
|
@ -548,8 +548,8 @@ Switch item=CinemaLight label="Cinema light" visibility=[TV_Power==ON]
|
|||
Switch item=LawnSprinkler visibility=[Day_Time=="Morning", Day_Time=="Afternoon", Temperature>19]
|
||||
```
|
||||
|
||||
In the third example above, a control for a lawn sprinkler will be visible if it is Morning, *OR* if it is Afternoon, *OR* if the temperature is above 19 °C.
|
||||
Combining multiple conditions, for example Morning *AND* above 19 °C is not supported.
|
||||
In the third example above, a control for a lawn sprinkler will be visible if it is Morning, _OR_ if it is Afternoon, _OR_ if the temperature is above 19 °C.
|
||||
Combining multiple conditions, for example Morning _AND_ above 19 °C is not supported.
|
||||
To control visibility based upon combining multiple Items, or on more complex conditions, consider defining and using an additional intermediate Item that is set by a Rule.
|
||||
Rules have a rich set of features that can support more involved scenarios.
|
||||
|
||||
|
|
Loading…
Reference in New Issue