[openwebnet] Fixed handling of ZigBee USB gateway and devices (fixes #8915 #8917 #8962) (2.5.x) (#9141)

Signed-off-by: Massimo Valla <mvcode00@gmail.com>
This commit is contained in:
M Valla 2020-11-28 13:44:01 +01:00 committed by GitHub
parent ed798b7ad7
commit 00a02158aa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 263 additions and 123 deletions

View File

@ -9,7 +9,7 @@ The binding supports:
- commands from openHAB and feedback (events) from BUS/SCS and wireless network
![F454 Gateway](doc/F454_gateway.png)
![USB ZigBee Gateway](doc/USB_gateway.jpg)
![ZigBee USB Gateway](doc/USB_gateway.jpg)
## Supported Things
@ -35,19 +35,19 @@ The following Things and OpenWebNet `WHOs` are supported:
### For BUS/SCS
| Category | WHO | Thing Type IDs | Description | Status |
| -------------------- | :----------: | :---------------------------------: | ----------------------------------------------------------- | ---------------- |
| Gateway Management | `13` | `bus_gateway` | Any IP gateway supporting OpenWebNet protocol should work (e.g. F454 / MyHOMEServer1 / MH202 / F455 / MH200N, ...) | Successfully tested: F454, MyHOMEServer1, MyHOME_Screen10, F455, F452, F453AV, MH201, MH202, MH200N. Some connection stability issues/gateway resets reported with MH202 |
| Lighting | `1` | `bus_on_off_switch`, `bus_dimmer` | BUS switches and dimmers. | Successfully tested: F411/2, F411/4, F411U2, F422, F429. Some discovery issues reported with F429 (DALI Dimmers) |
| Automation | `2` | `bus_automation` | BUS roller shutters, with position feedback and auto-calibration | Successfully tested: LN4672M2 |
| Category | WHO | Thing Type IDs | Description | Status |
| -------------------- | :----------: | :------------------------------------------: | -------------------------------------------------------------- | ---------------- |
| Gateway Management | `13` | `bus_gateway` | Any IP gateway supporting OpenWebNet protocol should work (e.g. F454 / MyHOMEServer1 / MH202 / F455 / MH200N, ...) | Successfully tested: F454, MyHOMEServer1, MyHOME_Screen10, F455, F452, F453AV, MH201, MH202, MH200N. Some connection stability issues/gateway resets reported with MH202 |
| Lighting | `1` | `bus_on_off_switch`, `bus_dimmer` | BUS switches and dimmers | Successfully tested: F411/2, F411/4, F411U2, F422, F429. Some discovery issues reported with F429 (DALI Dimmers) |
| Automation | `2` | `bus_automation` | BUS roller shutters, with position feedback and auto-calibration | Successfully tested: LN4672M2 |
### For ZigBee (Radio)
| Category | WHO | Thing Type IDs | Description | Status |
| ---------- | :---: | :-------------------------------: | :-------------------------------------------------------------------: | ------------------------------------ |
| Gateway | `13` | `zb_gateway` | Wireless ZigBee USB Gateway (models: BTI-3578 / LG 088328) | Tested: BTI-3578 and LG 088328 |
| Lighting | `1` | `zb_dimmer`, `zb_on_off_switch`, `zb_on_off_switch2u` | ZigBee dimmers, switches and 2-unit switches | Tested: BTI-4591, BTI-3584, BTI-4585 |
| Automation | `2` | `zb_automation` | ZigBee roller shutters | |
| Category | WHO | Thing Type IDs | Description | Status |
| -------------------- | :----: | :-------------------------------: | :-------------------------------------------------------------------: | ------------------------------------ |
| Gateway Management | `13` | `zb_gateway` | ZigBee USB Gateway (models: BTI-3578 / LG 088328) | Tested: BTI-3578 and LG 088328 |
| Lighting | `1` | `zb_dimmer`, `zb_on_off_switch`, `zb_on_off_switch2u` | ZigBee dimmers, switches and 2-unit switches | Tested: BTI-4591, BTI-3584, BTI-4585 |
| Automation | `2` | `zb_automation` | ZigBee roller shutters | |
## Discovery
@ -64,15 +64,15 @@ For other gateways you can add them manually, see [Thing Configuration](#thing-c
#### Discovery by Activation
Devices can also be discovered if activated while an Inbox Scan is active: start a new Scan, wait 15-20 seconds and then _while the Scan is still active_ (spinning arrow in Inbox), activate the physical device (for example dim the dimmer) to have it discovered by the binding.
BUS devices can also be discovered if activated while an Inbox Scan is active: start a new Scan, wait 15-20 seconds and then _while the Scan is still active_ (spinning arrow in Inbox), activate the physical device (for example dim the dimmer) to have it discovered by the binding.
If a device cannot be discovered automatically it's always possible to add it manually, see [Configuring Devices](#configuring-devices).
### ZigBee Discovery
- Zigbee USB gateway discovery is *not supported* at the moment: the gateway thing must be added manually see [Thing Configuration](#thing-configuration) below
- The ZigBee USB Gateway must be inserted in one of the USB ports of the openHAB computer before discovery is started
- ***IMPORTANT NOTE:*** As for other OH2 bindings using the USB/serial ports, on Linux the `openhab` user must be member of the `dialout` group, to be able to use USB/serial port: set the group with the following command:
- ZigBee USB gateway discovery is *not supported* at the moment: the gateway thing must be added manually see [Thing Configuration](#thing-configuration) below
- The ZigBee USB Gateway must be inserted in one of the USB ports of the openHAB computer before a discovery is started
- ***IMPORTANT NOTE:*** As for other openHAB bindings using the USB/serial ports, on Linux the `openhab` user must be member of the `dialout` group to be able to use USB/serial port; set the group with the following command:
```
$ sudo usermod -a -G dialout openhab
@ -105,12 +105,12 @@ Alternatively the BUS/SCS Gateway thing can be configured using the `.things` fi
### Configuring Wireless ZigBee USB Gateway
To add a ZigBee USB gateway manually using PaperUI: go to *Inbox > "+" > OpenWebNet > click `ADD MANUALLY`* and then select `ZigBee USB Gateway`.
To add a ZigBee USB Gateway manually using PaperUI: go to *Inbox > "+" > OpenWebNet > click `ADD MANUALLY`* and then select `ZigBee USB Gateway`.
Configuration parameters are:
- `serialPort` : the serial port where the ZigBee USB Gateway is connected (`String`, *mandatory*)
- Example: `COM3`
- Examples: `/dev/ttyUSB0` (Linux/RaPi), `COM3` (Windows)
### Configuring Devices
@ -119,20 +119,20 @@ Devices can be discovered automatically from Inbox after a gateway has been conf
Devices can be also added manually from PaperUI. For each device it must be configured:
- the associated gateway (`Bridge Selection` menu)
- the `WHERE` config parameter (`OpenWebNet Device Address`):
- example for BUS/SCS: Point to Point `A=2 PL=4` --> `WHERE="24"`
- example for BUS/SCS: Point to Point `A=6 PL=4` on local bus --> `WHERE="64#4#01"`
- example for ZigBee devices: use decimal format address without the UNIT part and network: ZigBee `WHERE=414122201#9` --> `WHERE="4141222"`
- the `where` config parameter (`OpenWebNet Device Address`):
- example for BUS/SCS device with WHERE address Point to Point `A=2 PL=4` --> `where="24"`
- example for BUS/SCS device with WHERE address Point to Point `A=03 PL=11` on local bus --> `where="0311#4#01"`
- example for ZigBee devices: `where=765432101#9`. The ID of the device (ADDR part) is usually written in hexadecimal on the device itself, for example `ID 0074CBB1`: convert to decimal (`7654321`) and add `01#9` at the end to obtain `where=765432101#9`. For 2-unit switch devices (`zb_on_off_switch2u`), last part should be `00#9`.
## Channels
Devices support some of the following channels:
| Channel Type ID (channel ID) | Item Type | Description | Read/Write |
|--------------------------|---------------|-------------------------------------------------------------------------|:----------:|
| `switch` | Switch | To switch the device `ON` and `OFF` | R/W |
| `brightness` | Dimmer | To adjust the brightness value (Percent, `ON`, `OFF`) | R/W |
| `shutter` | Rollershutter | To activate roller shutters (`UP`, `DOWN`, `STOP`, Percent - [see Shutter position](#shutter-position)) | R/W |
| Channel Type ID (channel ID) | Item Type | Description | Read/Write |
|------------------------------------------------|---------------|---------------------------------------------------------|:----------:|
| `switch` or `switch_01`/`02` for ZigBee | Switch | To switch the device `ON` and `OFF` | R/W |
| `brightness` | Dimmer | To adjust the brightness value (Percent, `ON`, `OFF`) | R/W |
| `shutter` | Rollershutter | To activate roller shutters (`UP`, `DOWN`, `STOP`, Percent - [see Shutter position](#shutter-position)) | R/W |
### Notes on channels
@ -151,36 +151,47 @@ It's possible to enter a value manually or set `shutterRun=AUTO` (default) to ca
### openwebnet.things:
BUS gateway and things configuration:
```xtend
Bridge openwebnet:bus_gateway:mybridge "MyHOMEServer1" [ host="192.168.1.35", passwd="abcde", port=20000, discoveryByActivation=false ] {
bus_on_off_switch LR_switch "Living Room Light" [ where="51" ]
bus_dimmer LR_dimmer "Living Room Dimmer" [ where="25#4#01" ]
bus_dimmer LR_dalidimmer "Living Room Dali-Dimmer" [ where="0311#4#01" ]
bus_automation LR_shutter "Living Room Shutter" [ where="93", shutterRun="10050"]
bus_on_off_switch LR_switch "Living Room Light" [ where="51" ]
bus_dimmer LR_dimmer "Living Room Dimmer" [ where="0311#4#01" ]
bus_automation LR_shutter "Living Room Shutter" [ where="93", shutterRun="10050"]
}
```
```
ZigBee USB Gateway and things configuration - for radio devices:
```xtend
// ZigBee USB Gateway configuration for radio devices
Bridge openwebnet:zb_gateway:myZBgateway [serialPort="COM3"] {
zb_dimmer myzigbeedimmer [ where="123456700#9"]
zb_on_off_switch myzigbeeswitch [ where="765432200#9"]
zb_dimmer myZB_dimmer [ where="765432101#9"]
zb_on_off_switch myZB_switch [ where="765432201#9"]
zb_on_off_switch2u myZB_2U_switch [ where="765432300#9"]
}
```
### openwebnet.items:
Items (Light, Dimmer, etc.) will be discovered by Google Assistant/Alexa/HomeKit if their tags are configured like in the example.
Items (Light, Dimmer, etc.) will be discovered by Google Assistant/Alexa/HomeKit if their tags are configured like in the example:
```xtend
Switch iLR_switch "Light" <light> (gLivingRoom) [ "Lighting" ] { channel="openwebnet:bus_on_off_switch:mybridge:LR_switch:switch" }
Dimmer iLR_dimmer "Dimmer [%.0f %%]" <DimmableLight> (gLivingRoom) [ "Lighting" ] { channel="openwebnet:bus_dimmer:mybridge:LR_dimmer:brightness" }
Dimmer iLR_dalidimmer "Dali-Dimmer [%.0f %%]" <DimmableLight> (gLivingRoom) [ "Lighting" ] { channel="openwebnet:bus_dimmer:mybridge:LR_dalidimmer:brightness" }
/* For Dimmers, use category DimmableLight to have Off/On switch in addition to the Percent slider in PaperUI */
Rollershutter iLR_shutter "Shutter [%.0f %%]" <rollershutter> (gShutters, gLivingRoom) [ "Blinds" ] { channel="openwebnet:bus_automation:mybridge:LR_shutter:shutter" }
```
Example items linked to ZigBee devices:
```xtend
Dimmer iDimmer "Dimmer [%.0f %%]" <DimmableLight> (gKitchen) [ "Lighting" ] { channel="openwebnet:zb_dimmer:myZBgateway:myZB_dimmer:brightness" }
Switch iSimpleSwitch "Kitchen Switch" <light> (gKitchen) [ "Lighting" ] { channel="openwebnet:zb_on_off_switch:myZBgateway:myZB_switch:switch_01" }
Switch iSwitch_01 "2U first light" <light> (gKitchen) [ "Lighting" ] { channel="openwebnet:zb_on_off_switch2u:myZBgateway:myZB_2U_switch:switch_01" }
Switch iSwitch_02 "2U second light" <light> (gKitchen) [ "Lighting" ] { channel="openwebnet:zb_on_off_switch2u:myZBgateway:myZB_2U_switch:switch_02" }
```
### openwebnet.sitemap
```xtend
@ -190,7 +201,6 @@ sitemap openwebnet label="OpenWebNet Binding Example Sitemap"
{
Default item=iLR_switch icon="light"
Default item=iLR_dimmer icon="light"
Default item=iLR_dalidimmer icon="light"
Default item=iLR_shutter
}
}

View File

@ -23,7 +23,7 @@
<dependency>
<groupId>com.github.openwebnet4j</groupId>
<artifactId>openwebnet4j</artifactId>
<version>0.3.1</version>
<version>0.3.2-1</version>
<scope>compile</scope>
</dependency>

View File

@ -329,8 +329,9 @@ public class OpenWebNetAutomationHandler extends OpenWebNetThingHandler {
updateMovingState(MOVING_STATE_STOPPED);
logger.debug("& {} & CALIBRATION - reached UP, now sending DOWN command...", deviceWhere);
calibrating = CALIBRATION_ACTIVATED;
if (deviceWhere != null) {
String w = deviceWhere.value();
Where dw = deviceWhere;
if (dw != null) {
String w = dw.value();
try {
send(Automation.requestMoveDown(w));
} catch (OWNException e) {

View File

@ -49,7 +49,9 @@ import org.openwebnet4j.message.FrameException;
import org.openwebnet4j.message.GatewayMgmt;
import org.openwebnet4j.message.Lighting;
import org.openwebnet4j.message.OpenMessage;
import org.openwebnet4j.message.What;
import org.openwebnet4j.message.Where;
import org.openwebnet4j.message.WhereZigBee;
import org.openwebnet4j.message.Who;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -71,6 +73,7 @@ public class OpenWebNetBridgeHandler extends ConfigStatusBridgeHandler implement
// ConcurrentHashMap of devices registered to this BridgeHandler
// association is: ownId (String) -> OpenWebNetThingHandler, with ownId = WHO.WHERE
private Map<String, @Nullable OpenWebNetThingHandler> registeredDevices = new ConcurrentHashMap<>();
private Map<String, Long> discoveringDevices = new ConcurrentHashMap<>();
protected @Nullable OpenGateway gateway;
private boolean isBusGateway = false;
@ -119,6 +122,7 @@ public class OpenWebNetBridgeHandler extends ConfigStatusBridgeHandler implement
"Could not connect to gateway before " + GATEWAY_ONLINE_TIMEOUT_SEC + "s");
}
}, GATEWAY_ONLINE_TIMEOUT_SEC, TimeUnit.SECONDS);
logger.debug("bridge {} initialization completed", thing.getUID());
} catch (OWNException e) {
logger.debug("gw.connect() returned OWNException: {}", e.getMessage());
// status is updated by callback onConnectionError()
@ -131,11 +135,11 @@ public class OpenWebNetBridgeHandler extends ConfigStatusBridgeHandler implement
* Init a ZigBee gateway based on config
*/
private @Nullable OpenGateway initZigBeeGateway() {
logger.debug("Initializing ZigBee USB gateway");
logger.debug("Initializing ZigBee USB Gateway");
OpenWebNetZigBeeBridgeConfig zbBridgeConfig = getConfigAs(OpenWebNetZigBeeBridgeConfig.class);
String serialPort = zbBridgeConfig.getSerialPort();
if (serialPort == null || serialPort.isEmpty()) {
logger.warn("Cannot connect to gateway. No serial port has been provided in Bridge configuration.");
logger.warn("Cannot connect ZigBee USB Gateway. No serial port has been provided in Bridge configuration.");
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
"@text/offline.conf-error-no-serial-port");
return null;
@ -152,7 +156,7 @@ public class OpenWebNetBridgeHandler extends ConfigStatusBridgeHandler implement
OpenWebNetBusBridgeConfig busBridgeConfig = getConfigAs(OpenWebNetBusBridgeConfig.class);
String host = busBridgeConfig.getHost();
if (host == null || host.isEmpty()) {
logger.warn("Cannot connect to gateway. No host/IP has been provided in Bridge configuration.");
logger.warn("Cannot connect to BUS Gateway. No host/IP has been provided in Bridge configuration.");
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
"@text/offline.conf-error-no-ip-address");
return null;
@ -206,7 +210,7 @@ public class OpenWebNetBridgeHandler extends ConfigStatusBridgeHandler implement
if (gw != null) {
gw.closeConnection();
gw.unsubscribe(this);
logger.debug("gateway {} connection closed and unsubscribed", gw.toString());
logger.debug("Gateway {} connection closed and unsubscribed", gw.toString());
gateway = null;
}
reconnecting = false;
@ -276,23 +280,54 @@ public class OpenWebNetBridgeHandler extends ConfigStatusBridgeHandler implement
}
private void discoverByActivation(BaseOpenMessage baseMsg) {
logger.debug("BridgeHandler.discoverByActivation() msg={}", baseMsg);
logger.debug("discoverByActivation: msg={}", baseMsg);
OpenWebNetDeviceDiscoveryService discService = deviceDiscoveryService;
if (discService == null) {
logger.warn("discoverByActivation: null OpenWebNetDeviceDiscoveryService, ignoring msg={}", baseMsg);
return;
}
if (baseMsg instanceof Lighting) {
if (baseMsg instanceof Lighting || baseMsg instanceof Automation) { // we support these types only
BaseOpenMessage bmsg = baseMsg;
if (baseMsg instanceof Lighting) {
What what = baseMsg.getWhat();
if (Lighting.WHAT.OFF.equals(what)) { // skipping OFF msg: cannot distinguish dimmer/switch
logger.debug("discoverByActivation: skipping OFF msg: cannot distinguish dimmer/switch");
return;
}
if (Lighting.WHAT.ON.equals(what)) { // if not already done just now, request light status to
// distinguish dimmer from switch
if (discoveringDevices.containsKey(ownIdFromMessage(baseMsg))) {
logger.debug(
"discoverByActivation: we just requested status for this device and it's ON -> it's a switch");
} else {
OpenGateway gw = gateway;
if (gw != null) {
try {
discoveringDevices.put(ownIdFromMessage(baseMsg),
Long.valueOf(System.currentTimeMillis()));
gw.send(Lighting.requestStatus(baseMsg.getWhere().value()));
return;
} catch (OWNException e) {
logger.warn("discoverByActivation: Exception while requesting light state: {}",
e.getMessage());
return;
}
}
}
}
discoveringDevices.remove(ownIdFromMessage(baseMsg));
}
OpenDeviceType type = null;
try {
type = baseMsg.detectDeviceType();
type = bmsg.detectDeviceType();
} catch (FrameException e) {
logger.warn("Exception while detecting device type: {}", e.getMessage());
}
if (type != null) {
discService.newDiscoveryResult(baseMsg.getWhere(), type, baseMsg);
discService.newDiscoveryResult(bmsg.getWhere(), type, bmsg);
} else {
logger.debug("discoverByActivation: no device type detected from msg: {}", baseMsg);
logger.debug("discoverByActivation: no device type detected from msg: {}", bmsg);
}
}
}
@ -354,7 +389,7 @@ public class OpenWebNetBridgeHandler extends ConfigStatusBridgeHandler implement
// let's try to get the Thing associated with this message...
if (baseMsg instanceof Lighting || baseMsg instanceof Automation) {
String ownId = ownIdFromMessage(baseMsg);
logger.debug("ownId={}", ownId);
logger.debug("ownIdFromMessage({}) --> {}", baseMsg, ownId);
OpenWebNetThingHandler deviceHandler = registeredDevices.get(ownId);
if (deviceHandler == null) {
OpenGateway gw = gateway;
@ -384,7 +419,7 @@ public class OpenWebNetBridgeHandler extends ConfigStatusBridgeHandler implement
return;
}
if (gw instanceof USBGateway) {
logger.info("------------------- CONNECTED to USB (ZigBee) gateway - USB port: {}",
logger.info("------------------- CONNECTED to ZigBee USB gateway - USB port: {}",
((USBGateway) gw).getSerialPortName());
} else {
logger.info("------------------- CONNECTED to BUS gateway '{}' ({}:{})", thing.getUID(),
@ -482,25 +517,24 @@ public class OpenWebNetBridgeHandler extends ConfigStatusBridgeHandler implement
}
/**
* Return a ownId string (=WHO.WHERE) from a deviceWhere thing config parameter (already normalized) and its
* handler.
* Return a ownId string (=WHO.WHERE) from the device Where address and handler
*
* @param deviceWhere the device WHERE config parameter
* @param handler the thing handler
* @return the ownId
* @param where the Where address (to be normalized)
* @param handler the device handler
* @return the ownId String
*/
protected String ownIdFromDeviceWhere(@Nullable String deviceWhere, OpenWebNetThingHandler handler) {
return handler.ownIdPrefix() + "." + deviceWhere;
protected String ownIdFromDeviceWhere(Where where, OpenWebNetThingHandler handler) {
return handler.ownIdPrefix() + "." + normalizeWhere(where);
}
/**
* Returns a ownId string (=WHO.WHERE) from a Where address and Who
* Returns a ownId string (=WHO.WHERE) from a Who and Where address
*
* @param where the Where address (to be normalized)
* @param who the Who
* @return the ownId
* @param where the Where address (to be normalized)
* @return the ownId String
*/
public String ownIdFromWhoWhere(Where where, Who who) {
public String ownIdFromWhoWhere(Who who, Where where) {
return who.value() + "." + normalizeWhere(where);
}
@ -510,45 +544,39 @@ public class OpenWebNetBridgeHandler extends ConfigStatusBridgeHandler implement
* @param baseMsg the BaseOpenMessage
* @return the ownId String
*/
private String ownIdFromMessage(BaseOpenMessage baseMsg) {
public String ownIdFromMessage(BaseOpenMessage baseMsg) {
return baseMsg.getWho().value() + "." + normalizeWhere(baseMsg.getWhere());
}
/**
* Transform a Where address into a Thing id string based on bridge type (BUS/USB ZigBee).
* '#' in WHERE are changed to 'h'
* Transform a Where address into a Thing id string
*
* @param where the Where address
* @return the thing Id
* @return the thing Id string
*/
public String thingIdFromWhere(Where where) {
return normalizeWhere(where).replace('#', 'h'); // '#' cannot be used in ThingUID;
return normalizeWhere(where); // '#' cannot be used in ThingUID;
}
/**
* Normalize a Where address for Thermo and Zigbee devices
* Normalize a Where address
*
* @param where the Where address
* @return the normalized address
* @return the normalized address as String
*/
public String normalizeWhere(Where where) {
String str = "";
if (isBusGateway) {
if (where.value().indexOf('#') < 0) { // no hash present
str = where.value();
} else if (where.value().indexOf("#4#") > 0) { // local bus: APL#4#bus
str = where.value();
} else if (where.value().indexOf('#') == 0) { // thermo zone via central unit: #0 or #Z (Z=[1-99]) --> Z
str = where.value().substring(1);
} else if (where.value().indexOf('#') > 0) { // thermo zone and actuator N: Z#N (Z=[1-99], N=[1-9]) -- > Z
str = where.value().substring(0, where.value().indexOf('#'));
} else {
logger.warn("normalizeWhere() unexpected WHERE: {}", where);
str = where.value();
}
return str;
String str = where.value();
if (where instanceof WhereZigBee) {
str = ((WhereZigBee) where).valueWithUnit(WhereZigBee.UNIT_ALL); // 76543210X#9 --> 765432100#9
} else {
return where.value();
if (str.indexOf("#4#") > 0) { // local bus: APL#4#bus
// no change needed
} else if (str.indexOf('#') == 0) { // Thermo zone via central unit: #0 or #Z (Z=[1-99]) --> Z
str = str.substring(1);
} else if (str.indexOf('#') > 0) { // Thermo zone and actuator N: Z#N (Z=[1-99], N=[1-9]) --> Z
str = str.substring(0, str.indexOf('#'));
}
}
return str.replace('#', 'h');
}
}

View File

@ -72,17 +72,22 @@ public abstract class OpenWebNetThingHandler extends BaseThingHandler {
if (!(deviceWhereConfig instanceof String)) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
"WHERE parameter in configuration is null or invalid");
return;
} else {
String deviceWhereStr = (String) getConfig().get(CONFIG_PROPERTY_WHERE);
Where w;
if (brH.isBusGateway()) {
w = new WhereLightAutom(deviceWhereStr);
} else {
w = new WhereZigBee(deviceWhereStr);
try {
if (brH.isBusGateway()) {
w = new WhereLightAutom(deviceWhereStr);
} else {
w = new WhereZigBee(deviceWhereStr);
}
} catch (IllegalArgumentException ia) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
"WHERE parameter in configuration is invalid");
return;
}
deviceWhere = w;
final String oid = brH.ownIdFromDeviceWhere(w.value(), this);
final String oid = brH.ownIdFromDeviceWhere(w, this);
ownId = oid;
Map<String, String> properties = editProperties();
properties.put(PROPERTY_OWNID, oid);
@ -91,11 +96,11 @@ public abstract class OpenWebNetThingHandler extends BaseThingHandler {
logger.debug("associated thing to bridge with ownId={}", ownId);
updateStatus(ThingStatus.UNKNOWN, ThingStatusDetail.NONE, "waiting state update...");
}
return;
}
} else {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
"No bridge associated, please assign a bridge in thing configuration.");
}
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
"No bridge associated, please assign a bridge in thing configuration.");
}
@Override
@ -105,8 +110,12 @@ public abstract class OpenWebNetThingHandler extends BaseThingHandler {
if (handler != null) {
OpenGateway gw = handler.gateway;
if (gw != null && !gw.isConnected()) {
logger.info("Cannot handle command {}:{} for {}: gateway is not connected", channel, command,
getThing().getUID());
logger.info("Cannot handle {} command for {}: gateway is not connected", command, getThing().getUID());
return;
}
if (deviceWhere == null) {
logger.info("Cannot handle {} command for {}: 'where' parameter is not configured or is invalid",
command, getThing().getUID());
return;
}
if (command instanceof RefreshType) {

View File

@ -81,6 +81,7 @@ public class BusGatewayUpnpDiscovery implements UpnpDiscoveryParticipant {
/**
* DeviceInfo bean to store device useful info (and log them)
*/
@NonNullByDefault
public class DeviceInfo {
@Nullable
private String friendlyName;

View File

@ -139,7 +139,7 @@ public class OpenWebNetDeviceDiscoveryService extends AbstractDiscoveryService
}
}
String ownId = bridgeHandler.ownIdFromWhoWhere(where, deviceWho);
String ownId = bridgeHandler.ownIdFromWhoWhere(deviceWho, where);
if (thingTypeUID == OpenWebNetBindingConstants.THING_TYPE_BUS_ON_OFF_SWITCH) {
if (bridgeHandler.getRegisteredDevice(ownId) != null) {
logger.debug("dimmer/switch with WHERE={} already registered, skipping this discovery result", where);
@ -152,27 +152,26 @@ public class OpenWebNetDeviceDiscoveryService extends AbstractDiscoveryService
DiscoveryResult discoveryResult = null;
String whereLabel = where.value();
String whereConfig = where.value();
if (where instanceof WhereZigBee && WhereZigBee.UNIT_02.equals(((WhereZigBee) where).getUnit())) {
logger.debug("UNIT=02 found (WHERE={})", where);
logger.debug("will remove previous result if exists");
logger.debug("UNIT=02 found (WHERE={}) -> will remove previous result if exists", where);
thingRemoved(thingUID); // remove previously discovered thing
// re-create thingUID with new type
thingTypeUID = OpenWebNetBindingConstants.THING_TYPE_ZB_ON_OFF_SWITCH_2UNITS;
thingLabel = OpenWebNetBindingConstants.THING_LABEL_ZB_ON_OFF_SWITCH_2UNITS;
thingUID = new ThingUID(thingTypeUID, bridgeUID, tId);
whereLabel = whereLabel.replace("02#", "00#"); // replace unit '02' with all unit '00'
whereConfig = ((WhereZigBee) where).valueWithUnit(WhereZigBee.UNIT_ALL); // replace unit '02' with '00'
logger.debug("UNIT=02, switching type from {} to {}",
OpenWebNetBindingConstants.THING_TYPE_ZB_ON_OFF_SWITCH,
OpenWebNetBindingConstants.THING_TYPE_ZB_ON_OFF_SWITCH_2UNITS);
}
Map<String, Object> properties = new HashMap<>(2);
properties.put(OpenWebNetBindingConstants.CONFIG_PROPERTY_WHERE, bridgeHandler.normalizeWhere(where));
properties.put(OpenWebNetBindingConstants.CONFIG_PROPERTY_WHERE, whereConfig);
properties.put(OpenWebNetBindingConstants.PROPERTY_OWNID, ownId);
if (thingTypeUID == OpenWebNetBindingConstants.THING_TYPE_GENERIC_DEVICE) {
thingLabel = thingLabel + " (WHO=" + deviceWho + ", WHERE=" + whereLabel + ")";
thingLabel = thingLabel + " (WHO=" + deviceWho + ", WHERE=" + whereConfig + ")";
} else {
thingLabel = thingLabel + " (WHERE=" + whereLabel + ")";
thingLabel = thingLabel + " (WHERE=" + whereConfig + ")";
}
discoveryResult = DiscoveryResultBuilder.create(thingUID).withThingType(thingTypeUID).withProperties(properties)
.withRepresentationProperty(OpenWebNetBindingConstants.PROPERTY_OWNID).withBridge(bridgeUID)

View File

@ -38,8 +38,8 @@
</parameter>
<parameter name="where" type="text" required="true">
<label>OpenWebNet Device Address (WHERE)</label>
<description>Example: A/PL address: A=1 PL=3 --> WHERE=13. On local bus: WHERE=13#4#01</description>
<label>OpenWebNet Device Address (where)</label>
<description>Example: A/PL address: A=1 PL=3 --> where=13. On local bus: where=13#4#01</description>
</parameter>
</config-description>
</thing-type>

View File

@ -27,8 +27,8 @@
<config-description>
<parameter name="where" type="text" required="true">
<label>OpenWebNet Device Address (WHERE)</label>
<description>Example: A/PL address: A=1 PL=3 --> WHERE=13. On local bus: WHERE=13#4#01</description>
<label>OpenWebNet Device Address (where)</label>
<description>Example: A/PL address: A=1 PL=3 --> where=13. On local bus: where=13#4#01</description>
</parameter>
</config-description>

View File

@ -27,8 +27,8 @@
<config-description>
<parameter name="where" type="text" required="true">
<label>OpenWebNet Device Address (WHERE)</label>
<description>Example: A/PL address: A=1 PL=3 --> WHERE=13. On local bus: WHERE=13#4#01</description>
<label>OpenWebNet Device Address (where)</label>
<description>Example: A/PL address: A=1 PL=3 --> where=13. On local bus: where=13#4#01</description>
</parameter>
</config-description>

View File

@ -24,7 +24,7 @@
<config-description>
<parameter name="where" type="text" required="true">
<label>OpenWebNet Device Address (WHERE)</label>
<label>OpenWebNet Device Address (where)</label>
<description>It identifies one OpenWebNet device</description>
</parameter>
</config-description>

View File

@ -38,9 +38,8 @@
<default>AUTO</default>
</parameter>
<parameter name="where" type="text">
<label>OpenWebNet Device Address</label>
<description>It identifies one ZigBee device. Use decimal format address without the UNIT part and network: ZigBee
WHERE=414122201#9 -> OpenWebNet Device Address = 4141222</description>
<label>OpenWebNet Device Address (where)</label>
<description>It identifies one ZigBee device. Example: 765432101#9</description>
<required>true</required>
</parameter>
</config-description>

View File

@ -27,9 +27,8 @@
<config-description>
<parameter name="where" type="text" required="true">
<label>OpenWebNet Device Address</label>
<description>It identifies one ZigBee device. Use decimal format address without the UNIT part and network: ZigBee
WHERE=414122201#9 -> OpenWebNet Device Address = 4141222</description>
<label>OpenWebNet Device Address (where)</label>
<description>It identifies one ZigBee device. Example: 765432101#9</description>
</parameter>
</config-description>

View File

@ -27,9 +27,8 @@
<config-description>
<parameter name="where" type="text" required="true">
<label>OpenWebNet Device Address</label>
<description>It identifies one ZigBee device. Use decimal format address without the UNIT part and network: ZigBee
WHERE=414122201#9 -> OpenWebNet Device Address = 4141222</description>
<label>OpenWebNet Device Address (where)</label>
<description>It identifies one ZigBee device. Example: 765432101#9</description>
</parameter>
</config-description>

View File

@ -28,9 +28,8 @@
<config-description>
<parameter name="where" type="text" required="true">
<label>OpenWebNet Device Address</label>
<description>It identifies one ZigBee device. Use decimal format address without the UNIT part and network: ZigBee
WHERE=414122201#9 -> OpenWebNet Device Address = 4141222</description>
<label>OpenWebNet Device Address (where)</label>
<description>It identifies one ZigBee device. Example: 765432100#9 (use unit=00 at the end)</description>
</parameter>
</config-description>

View File

@ -0,0 +1,96 @@
/**
* Copyright (c) 2010-2020 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.openwebnet.handler;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.smarthome.core.thing.Bridge;
import org.junit.Test;
import org.openwebnet4j.message.Lighting;
import org.openwebnet4j.message.Where;
import org.openwebnet4j.message.WhereLightAutom;
import org.openwebnet4j.message.WhereZigBee;
import org.openwebnet4j.message.Who;
/**
* Test class for {@link OpenWebNetBridgeHandler#ownID} and ThingID calculation using {@link OpenWebNetBridgeHandler}
* methods: normalizeWhere(), ownIdFromWhoWhere(), ownIdFromMessage(), thingIdFromWhere()
*
* @author Massimo Valla - Initial contribution
*/
@NonNullByDefault
public class OwnIdTest {
// @formatter:off
/**
*
* deviceWhere
* (DevAddrParam)
* TYPE WHERE = normalizeWhere() ownId ThingID
* ---------------------------------------------------------------------------------
* Zigbee Switch 789309801#9 789309800h9 1.789309800h9 789309800h9
* Zigbee Switch_2u u1 789301201#9 789301200h9 1.789309800h9 789309800h9
* Zigbee Switch_2u u2 789301202#9 789301200h9 1.789309800h9 789309800h9
* BUS Switch 51 51 1.51 51
* BUS Local Bus 25#4#01 25h4h01 1.25h4h01 25h4h01
* BUS Autom 93 93 2.93 93
* BUS Thermo #1 or 1 1 4.1 1
* BUS TempSensor 500 500 4.500 500
* BUS Energy 51 51 18.51 51
* BUS CEN 51 51 15.51 51
* BUS CEN+ 212 212 25.212 212
* BUS DryContact 399 399 25.399 399
*
*/
// @formatter:on
public enum TEST {
zb_switch(new WhereZigBee("789309801#9"), Who.fromValue(1), "789309800h9", "1.789309800h9", "789309800h9"),
zb_switch_2u_1(new WhereZigBee("789301201#9"), Who.fromValue(1), "789301200h9", "1.789301200h9", "789301200h9"),
zb_switch_2u_2(new WhereZigBee("789301202#9"), Who.fromValue(1), "789301200h9", "1.789301200h9", "789301200h9"),
bus_switch(new WhereLightAutom("51"), Who.fromValue(1), "51", "1.51", "51"),
bus_localbus(new WhereLightAutom("25#4#01"), Who.fromValue(1), "25h4h01", "1.25h4h01", "25h4h01");
// bus_thermo("#1", "4", "1", "4.1", "1"),
// bus_tempSensor("500", "4", "500", "4.500", "500"),
// bus_energy("51", "18", "51", "18.51", "51");
public final Where where;
public final Who who;
public final String norm, ownId, thingId;
private TEST(Where where, Who who, String norm, String ownId, String thingId) {
this.where = where;
this.who = who;
this.norm = norm;
this.ownId = ownId;
this.thingId = thingId;
}
}
@Test
public void testOwnId() {
Bridge mockBridge = mock(Bridge.class);
OpenWebNetBridgeHandler brH = new OpenWebNetBridgeHandler(mockBridge);
for (int i = 0; i < TEST.values().length; i++) {
TEST test = TEST.values()[i];
// System.out.println("testing where=" + test.where);
assertEquals(test.norm, brH.normalizeWhere(test.where));
assertEquals(test.ownId, brH.ownIdFromWhoWhere(test.who, test.where));
assertEquals(test.ownId, brH.ownIdFromMessage(Lighting.requestTurnOn(test.where.value())));
assertEquals(test.thingId, brH.thingIdFromWhere(test.where));
}
}
}