Updated external content (Jenkins build 371)

pull/1569/head
openHAB Build Server 2021-04-11 04:51:50 +00:00
parent 8dc023d2d6
commit c27c8d8ccc
5 changed files with 426 additions and 59 deletions

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,141 @@
---
id: ventaair
label: VentaAir
title: VentaAir - Bindings
type: binding
description: "This binding is for air humidifiers from Venta Air."
since: 3x
install: manual
---
<!-- Attention authors: Do not edit directly. Please add your changes to the appropriate source repository -->
{% include base.html %}
# VentaAir Binding
This binding is for air humidifiers from Venta Air.
Thankfully the vendor allows for communicating within the local network without needing any internet access or accounts.
This is even stated in the official manual.
Hence this binding communicates locally with the humidifier and is able to read out the current measurements and settings, as well as changing the settings.
## Supported Things
It currently supports the LW60-T device (`ThingType`: "lw60t") as well as a `ThingType` ("generic") for other models.
For now the generic `ThingType` only adds the "boost" channel, but in the status reply from the device there is more which could be added in the future by someone who owns a different device.
## Discovery
This binding supports an automatic discovery for humidifiers that are connected to the local network and which are in the same broadcast domain.
To do so, the binding listens to UDP port 48000 for data and creates `DiscoveryResult`s based on the received data from the device.
This comes in handy for getting the MAC address for the device for example.
Once the `DiscoveryResult` is added as a `Thing`, a connection to the device will be created and it will beep, showing a confirmation screen that the device "openHAB" would like to get access.
After confirming this request, the user can link its items to receive data or control the device.
## Thing Configuration
There are three mandatory configuration parameters for a thing: `ipAddress`, `macAddress` and `deviceType`.
| parameter | required | description |
|----------|------------|-------------------------------------------|
| ipAddress | Y | The IP Address or hostname of the device. |
| macAddress | Y | The MAC address of the device. |
| deviceType | Y | Defines the type of device. It is an integer value and its best to use the automatic discovery to obtain it from the device. |
| pollingTime | N | The time interval in seconds in which the data should be polled from the device, default is 10 seconds. |
| hash | N | It is a negative integer value and it is used by the device to identify a connection to a client, like the App from the vendor for example. (*) |
(*) I do not know whether there are devices which are restricted to only one client, so I added this parameter to allow the user to set the same value as his App on the phone (can be obtained via sniffing the network).
However, the LW60-T allows for multiple connections to different clients, identified by different `hash` values at the same time without issues.
By default the binding uses "-42", so a new ID that is not known to the device and hence it asks for confirmation, see the Discovery section.
Example Thing configuration:
```
Thing ventaair:lw60t:humidifier [ ipAddress="192.168.42.69", macAddress="f8:f0:05:a6:4e:03", deviceType=4, pollingTime=10, hash=-42]
```
## Channels
These are the channels that are currently supported:
| channel | type (RO=read-only) | description |
|----------|--------|------------------------------|
| power | Switch | This is the power on/off channel |
| fanSpeed | Number | This is the channel to control the steps (in range 0-5 where 0 means "off") for the speed of the fan |
| targetHumidity | Number | This channel sets the target humidity (in percent) that should be tried to reach by the device (allowed values: 30-70) |
| timer | Number | This channel sets the power off timer to the set value in hours, i.e. 3 = turn off in 3 hours from now (allowed values: 0-9 where 0 means "off") |
| sleepMode | Switch | This channel controls the sleep mode of the device (dims the display and slows down the fan) |
| childLock | Switch | This is the control channel for the child lock |
| automatic | Switch | This is the control channel to start the automatic operation mode of the device |
| cleanMode | Switch (RO) | This is the channel that indicates if the device is in the cleaning mode |
| temperature | Number:Temperature (RO) | This channel provides the current measured temperature in Celsius or Fahrenheit as configured on the device |
| humidity | Number:Dimensionless (RO) | This channel provides the humidity measured by the device in percent |
| waterLevel | Number (RO) | This channel indicates the water level of the tank where 1 is equal to the yellow "refill tank" warning on the device/App |
| fanRPM | Number (RO) | This channel provides the speed of the ventilation fan |
| timerTimePassed | Number:Time (RO) | If a timer has been set, this channel provides the minutes since when the timer was started |
| operationTime | Number:Time (RO) | This channel provides the operation time of the device in hours |
| discReplaceTime | Number:Time (RO) | This channel provides the time in how many hours the cleaning disc should be replaced |
| cleaningTime | Number:Time (RO) | This channel provides the time in how many hours the device should be cleaned |
| boost | Switch | This is the control channel for the boost mode (on some devices that supports it) |
## Full Example
Things:
```
Thing ventaair:lw60t:humidifier [ ipAddress="192.168.42.69", macAddress="f8:f0:05:a6:4e:03", deviceType=4, pollingTime=10, hash=-42]
```
Items:
```
Group gHumidifier "Air Humidifier" <humidity>
Switch Humidifier_Power "Power: [%s]" (gHumidifier) { channel="ventaair:lw60t:humidifier:power" }
Number Humidifier_FanSpeed "FanSpeed: [%s]" (gHumidifier) { channel="ventaair:lw60t:humidifier:fanSpeed" }
Number Humidifier_TargetHum "Target Humidity: [%s]" (gHumidifier) { channel="ventaair:lw60t:humidifier:targetHumidity" }
Number Humidifier_Timer "Timer: [%s]" (gHumidifier) { channel="ventaair:lw60t:humidifier:timer" }
Switch Humidifier_SleepMode "SleepMode:" (gHumidifier) { channel="ventaair:lw60t:humidifier:sleepMode" }
Switch Humidifier_ChildLock "ChildLock:" (gHumidifier) { channel="ventaair:lw60t:humidifier:childLock" }
Switch Humidifier_Automatic "Automatic:" (gHumidifier) { channel="ventaair:lw60t:humidifier:automatic" }
Switch Humidifier_CleaningMode "Cleaning mode:" (gHumidifier) { channel="ventaair:lw60t:humidifier:cleanMode" }
Number:Temperature Humidifier_Temperature "Temp: [%.1f %unit%]" (gHumidifier) { channel="ventaair:lw60t:humidifier:temperature" }
Number:Temperature Humidifier_temperatureF "Temp: [%.1f °F]" (gHumidifier) { channel="ventaair:lw60t:humidifier:temperature" }
Number Humidifier_Humidity "Humidity: [%.1f %%]" (gHumidifier) { channel="ventaair:lw60t:humidifier:humidity" }
Number Humidifier_WaterLevel "WaterLevel: [%d]" (gHumidifier) { channel="ventaair:lw60t:humidifier:waterLevel" }
Number Humidifier_FanRPM "Fan RPM: [%d]" (gHumidifier) { channel="ventaair:lw60t:humidifier:fanRPM" }
Number Humidifier_TimerTime "Timer time: [%d]" (gHumidifier) { channel="ventaair:lw60t:humidifier:timerTimePassed" }
Number Humidifier_OpTime "Operation Time: [%d]" (gHumidifier) { channel="ventaair:lw60t:humidifier:operationTime" }
Number Humidifier_ReplaceTime "Disc replace in (h): [%d]" (gHumidifier) { channel="ventaair:lw60t:humidifier:discReplaceTime" }
Number Humidifier_CleaningTime "Cleaning in (h): [%d]" (gHumidifier) { channel="ventaair:lw60t:humidifier:cleaningTime" }
//for generic devices:
Switch boost "Boost:" { channel="ventaair:generic:humidifier:boost" }
```
Sitemap:
```
Text item=Humidifier_Humidity
Text item=Humidifier_Temperature
Switch item=Humidifier_Power
Switch item=Humidifier_SleepMode
Switch item=Humidifier_FanSpeed icon="fan" mappings=[0="0", 1="1", 2="2", 3="3", 4="4", 5="5"]
Switch item=Humidifier_TargetHum mappings=[30="30", 35="35", 40="40", 45="45", 50="50", 55="55", 60="60", 65="65", 70="70"]
Switch item=Humidifier_Timer mappings=[0="0", 1="1", 3="3", 5="5", 7="7", 9="9"]
Text item=Humidifier_WaterLevel
Text item=Humidifier_FanRPM
Text item=Humidifier_OpTime
Text item=Humidifier_ReplaceTime
Text item=Humidifier_CleaningTime
Text item=Humidifier_TimerTime
Switch item=Humidifier_CleaningModeActive
Switch item=Humidifier_ChildLock
Switch item=Humidifier_Automatic
```

View File

@ -29,22 +29,10 @@ This service is provided "AS IS", and the user takes full responsibility of any
## Table of Contents
<!-- Using MarkdownTOC plugin for Sublime Text to update the table of contents (TOC) -->
<!-- MarkdownTOC depth=3 autolink=true bracket=round -->
{::options toc_levels="2..4"/}
- [Prerequisites](#prerequisites)
- [Setting Up an Amazon Account](#setting-up-an-amazon-account)
- [Configuration](#configuration)
- [Basic configuration](#basic-configuration)
- [Configuration Using Credentials File](#configuration-using-credentials-file)
- [Advanced Configuration](#advanced-configuration)
- [Details](#details)
- [Tables Creation](#tables-creation)
- [Caveats](#caveats)
- [Developer Notes](#developer-notes)
- [Updating Amazon SDK](#updating-amazon-sdk)
<!-- /MarkdownTOC -->
- TOC
{:toc}
## Prerequisites
@ -69,9 +57,53 @@ Please also note possible [Free Tier](https://aws.amazon.com/free/) benefits.
## Configuration
This service can be configured in the file `services/dynamodb.cfg`.
This service can be configured using the MainUI or using persistence configuration file `services/dynamodb.cfg`.
### Basic configuration
In order to configure the persistence service, you need to configure two things:
1. Table schema revision to use
2. AWS credentials to access DynamoDB
### Table schema
The DynamoDB persistence addon provides two different table schemas: "new" and "legacy".
As the name implies, "legacy" is offered for backwards-compatibility purpose for old users who like to access the data that is already stored in DynamoDB.
All users are advised to transition to "new" table schema, which is more optimized.
At this moment there is no supported way to migrate data from old format to new.
#### New table schema
Configure the addon to use new schema by setting `table` parameter (name of the table).
Only one table will be created for all data. The table will have the following fields
| Attribute | Type | Data type | Description |
| --------- | ------ | --------- | --------------------------------------------- |
| `i` | String | Yes | Item name |
| `t` | Number | Yes | Timestamp in milliepoch |
| `s` | String | Yes | State of the item, stored as DynamoDB string. |
| `n` | Number | Yes | State of the item, stored as DynamoDB number. |
| `exp` | Number | Yes | Expiry date for item, in epoch seconds |
Other notes
- `i` and `t` forms the composite primary key (partition key, sort key) for the table
- Only one of `s` or `n` attributes are specified, not both. Most items are converted to number type for most compact representation.
- Compared to legacy format, data overhead is minimizing by using short attribute names, number timestamps and having only single table.
- `exp` attribute is used with DynamoDB Time To Live (TTL) feature to automatically delete old data
#### Legacy schema
Configure the addon to use legacy schema by setting `tablePrefix` parameter.
- When an item is persisted via this service, a table is created (if necessary).
- The service will create at most two tables for different item types.
- The tables will be named `<tablePrefix><item-type>`, where the `<item-type>` is either `bigdecimal` (numeric items) or `string` (string and complex items).
- Each table will have three columns: `itemname` (item name), `timeutc` (in ISO 8601 format with millisecond accuracy), and `itemstate` (either a number or string representing item state).
### Credentials Configuration Using Access Key and Secret Key
| Property | Default | Required | Description |
| --------- | ------- | :------: | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
@ -79,7 +111,7 @@ This service can be configured in the file `services/dynamodb.cfg`.
| secretKey | | Yes | secret key as shown in [Setting up Amazon account](#setting-up-an-amazon-account). |
| region | | Yes | AWS region ID as described in [Setting up Amazon account](#setting-up-an-amazon-account). The region needs to match the region that was used to create the user. |
### Configuration Using Credentials File
### Credentials Configuration Using Credentials File
Alternatively, instead of specifying `accessKey` and `secretKey`, one can configure a configuration profile file.
@ -109,47 +141,27 @@ aws_secret_access_key=testSecretKey
In addition to the configuration properties above, the following are also available:
| Property | Default | Required | Description |
| -------------------------- | ---------- | :------: | -------------------------------------------------------------------------------------------------- |
| readCapacityUnits | 1 | No | read capacity for the created tables |
| writeCapacityUnits | 1 | No | write capacity for the created tables |
| tablePrefix | `openhab-` | No | table prefix used in the name of created tables |
| bufferCommitIntervalMillis | 1000 | No | Interval to commit (write) buffered data. In milliseconds. |
| bufferSize | 1000 | No | Internal buffer size in datapoints which is used to batch writes to DynamoDB every `bufferCommitIntervalMillis`. |
Typically you should not need to modify parameters related to buffering.
| Property | Default | Required | Description |
| ------------------ | ------- | :------: | ----------------------------------------------------------- |
| expireDays | (null) | No | Expire time for data in days (relative to stored timestamp) |
| readCapacityUnits | 1 | No | read capacity for the created tables |
| writeCapacityUnits | 1 | No | write capacity for the created tables |
Refer to Amazon documentation on [provisioned throughput](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.ProvisionedThroughput.html) for details on read/write capacity.
DynamoDB Time to Live (TTL) setting is configured using `expireDays`.
All item- and event-related configuration is done in the file `persistence/dynamodb.persist`.
## Details
### Tables Creation
When an item is persisted via this service, a table is created (if necessary).
Currently, the service will create at most two tables for different item types.
The tables will be named `<tablePrefix><item-type>`, where the `<item-type>` is either `bigdecimal` (numeric items) or `string` (string and complex items).
Each table will have three columns: `itemname` (item name), `timeutc` (in ISO 8601 format with millisecond accuracy), and `itemstate` (either a number or string representing item state).
## Buffering
By default, the service is asynchronous which means that data is not written immediately to DynamoDB but instead buffered in-memory.
The size of the buffer, in terms of datapoints, can be configured with `bufferSize`.
Every `bufferCommitIntervalMillis` the whole buffer of data is flushed to DynamoDB.
It is recommended to have the buffering enabled since the synchronous behaviour (writing data immediately) might have adverse impact to the whole system when there is many items persisted at the same time.
The buffering can be disabled by setting `bufferSize` to zero.
The defaults should be suitable in many use cases.
### Caveats
When the tables are created, the read/write capacity is configured according to configuration.
However, the service does not modify the capacity of existing tables.
As a workaround, you can modify the read/write capacity of existing tables using the [Amazon console](https://aws.amazon.com/console/).
Similar caveat applies for DynamoDB Time to Live (TTL) setting `expireDays`.
## Developer Notes
### Updating Amazon SDK
@ -157,20 +169,15 @@ As a workaround, you can modify the read/write capacity of existing tables using
1. Clean `lib/*`
2. Update SDK version in `scripts/fetch_sdk_pom.xml`. You can use the [maven online repository browser](https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk-dynamodb) to find the latest version available online.
3. `scripts/fetch_sdk.sh`
4. Copy `scripts/target/site/dependencies.html` and `scripts/target/dependency/*.jar` to `lib/`
5. Generate `build.properties` entries
`ls lib/*.jar | python -c "import sys; print(' ' + ',\\\\\\n '.join(map(str.strip, sys.stdin.readlines())))"`
6. Generate `META-INF/MANIFEST.MF` `Bundle-ClassPath` entries
`ls lib/*.jar | python -c "import sys; print(' ' + ',\\n '.join(map(str.strip, sys.stdin.readlines())))"`
7. Generate `.classpath` entries
`ls lib/*.jar | python -c "import sys;pre='<classpathentry exported=\"true\" kind=\"lib\" path=\"';post='\"/>'; print('\\t' + pre + (post + '\\n\\t' + pre).join(map(str.strip, sys.stdin.readlines())) + post)"`
4. Copy printed dependencies to `pom.xml`
After these changes, it's good practice to run integration tests (against live AWS DynamoDB) in `org.openhab.persistence.dynamodb.test` bundle.
See README.md in the test bundle for more information how to execute the tests.
### Running integration tests
To run integration tests, one needs to provide AWS credentials.
When running integration tests, local temporary DynamoDB server is used, emulating the real AWS DynamoDB API.
One can configure AWS credentials to run the test against real AWS DynamoDB for most realistic tests.
Eclipse instructions
@ -182,7 +189,4 @@ Eclipse instructions
-DDYNAMODBTEST_REGION=REGION-ID
-DDYNAMODBTEST_ACCESS=ACCESS-KEY
-DDYNAMODBTEST_SECRET=SECRET
````
The tests will create tables with prefix `dynamodb-integration-tests-`.
Note that when tests are begun, all data is removed from that table!
````

View File

@ -0,0 +1,155 @@
<?xml version="1.0" encoding="UTF-8"?>
<thing:thing-descriptions bindingId="ventaair"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
<channel-type id="fanSpeed">
<item-type>Number</item-type>
<label>Fan Speed</label>
<description>Speed of the ventilation fan (0-5)</description>
<state readOnly="false">
<options>
<option value="0">Off</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
</options>
</state>
</channel-type>
<channel-type id="targetHumidity">
<item-type>Number</item-type>
<label>Target Humidity</label>
<description>Target Humidity (30-70)</description>
<category>Humidity</category>
<state readOnly="false">
<options>
<option value="30">30 %</option>
<option value="35">35 %</option>
<option value="40">40 %</option>
<option value="45">45 %</option>
<option value="50">50 %</option>
<option value="55">55 %</option>
<option value="60">60 %</option>
<option value="65">65 %</option>
<option value="70">70 %</option>
</options>
</state>
</channel-type>
<channel-type id="timer">
<item-type>Number</item-type>
<label>Timer</label>
<description>Timer (0,1,3,5,7,9h)</description>
<state readOnly="false">
<options>
<option value="0">Off</option>
<option value="1">1 hour</option>
<option value="3">3 hours</option>
<option value="5">5 hours</option>
<option value="7">7 hours</option>
<option value="9">9 hours</option>
</options>
</state>
</channel-type>
<channel-type id="timerTimePassed">
<item-type>Number:Time</item-type>
<label>Timer Time Passed</label>
<description>Time that has passed since set by the Timer</description>
<state readOnly="true"/>
</channel-type>
<channel-type id="sleepMode">
<item-type>Switch</item-type>
<label>Sleep Mode</label>
<description>Sleep Mode</description>
</channel-type>
<channel-type id="boost">
<item-type>Switch</item-type>
<label>Boost</label>
<description>Boost</description>
</channel-type>
<channel-type id="childLock">
<item-type>Switch</item-type>
<label>Child Lock</label>
<description>Child Lock</description>
</channel-type>
<channel-type id="automatic">
<item-type>Switch</item-type>
<label>Automatic</label>
<description>Automatic</description>
</channel-type>
<channel-type id="temperature">
<item-type>Number:Temperature</item-type>
<label>Temperature</label>
<description>Current Temperature</description>
<category>Temperature</category>
<state pattern="%.1f %unit%" readOnly="true"/>
</channel-type>
<channel-type id="humidity">
<item-type>Number:Dimenionsless</item-type>
<label>Humidity</label>
<description>Current Humidity</description>
<category>Humidity</category>
<state pattern="%.1f %unit%" readOnly="true"/>
</channel-type>
<channel-type id="waterLevel">
<item-type>Number</item-type>
<label>Water Level</label>
<description>Water Level</description>
<state readOnly="true">
<options>
<option value="0">Critical</option>
<option value="1">Refill tank</option>
<option value="2">OK</option>
<option value="3">Full</option>
</options>
</state>
</channel-type>
<channel-type id="fanRPM">
<item-type>Number</item-type>
<label>Fan RPM</label>
<description>Fan RPM</description>
<state pattern="%d RPM" readOnly="true"/>
</channel-type>
<channel-type id="cleanMode">
<item-type>Switch</item-type>
<label>Cleaning Mode</label>
<description>Device is in cleaning mode (ON)</description>
<state readOnly="true"/>
</channel-type>
<channel-type id="operationTime">
<item-type>Number:Time</item-type>
<label>Operation Time</label>
<description>Operation Time since the device was first started (in hours)</description>
<state pattern="%d" readOnly="true"/>
</channel-type>
<channel-type id="discReplaceTime">
<item-type>Number:Time</item-type>
<label>Hygiene Disc Replacement</label>
<description>Time until the Hygiene Disc should be replaced (in hours)</description>
<state pattern="%d" readOnly="true"/>
</channel-type>
<channel-type id="cleaningTime">
<item-type>Number:Time</item-type>
<label>Cleaning Time</label>
<description>Time until next cleaning (in hours)</description>
<state pattern="%d" readOnly="true"/>
</channel-type>
</thing:thing-descriptions>

View File

@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8"?>
<thing:thing-descriptions bindingId="ventaair"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
<thing-type id="lw60t">
<label>LW60-T VentaAir Humidifier</label>
<description>Thing for Venta Air LW60-T Humidifiers</description>
<channels>
<channel id="power" typeId="system.power"/>
<channel id="fanSpeed" typeId="fanSpeed"/>
<channel id="targetHumidity" typeId="targetHumidity"/>
<channel id="timer" typeId="timer"/>
<channel id="sleepMode" typeId="sleepMode"/>
<channel id="childLock" typeId="childLock"/>
<channel id="automatic" typeId="automatic"/>
<channel id="temperature" typeId="temperature"/>
<channel id="humidity" typeId="humidity"/>
<channel id="waterLevel" typeId="waterLevel"/>
<channel id="fanRPM" typeId="fanRPM"/>
<channel id="cleanMode" typeId="cleanMode"/>
<channel id="timerTimePassed" typeId="timerTimePassed"/>
<channel id="operationTime" typeId="operationTime"/>
<channel id="discReplaceTime" typeId="discReplaceTime"/>
<channel id="cleaningTime" typeId="cleaningTime"/>
</channels>
<representation-property>macAddress</representation-property>
<config-description-ref uri="thing-type:ventaair:humidifier"/>
</thing-type>
<!-- Generic type has boost channel and maybe in the future other channels -->
<thing-type id="generic">
<label>Generic Humidifier/Cleaner</label>
<description>Thing for Venta Air Humidifiers/Cleaners</description>
<channels>
<channel id="power" typeId="system.power"/>
<channel id="fanSpeed" typeId="fanSpeed"/>
<channel id="targetHumidity" typeId="targetHumidity"/>
<channel id="timer" typeId="timer"/>
<channel id="sleepMode" typeId="sleepMode"/>
<channel id="boost" typeId="boost"/>
<channel id="childLock" typeId="childLock"/>
<channel id="automatic" typeId="automatic"/>
<channel id="temperature" typeId="temperature"/>
<channel id="humidity" typeId="humidity"/>
<channel id="waterLevel" typeId="waterLevel"/>
<channel id="fanRPM" typeId="fanRPM"/>
<channel id="cleanMode" typeId="cleanMode"/>
<channel id="timerTimePassed" typeId="timerTimePassed"/>
<channel id="operationTime" typeId="operationTime"/>
<channel id="discReplaceTime" typeId="discReplaceTime"/>
<channel id="cleaningTime" typeId="cleaningTime"/>
</channels>
<representation-property>macAddress</representation-property>
<config-description-ref uri="thing-type:ventaair:humidifier"/>
</thing-type>
</thing:thing-descriptions>