Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[dominoswiss] Initial contribution #11585

Merged
merged 7 commits into from
Dec 11, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
/bundles/org.openhab.binding.digitalstrom/ @MichaelOchel @msiegele
/bundles/org.openhab.binding.dlinksmarthome/ @MikeJMajor
/bundles/org.openhab.binding.dmx/ @openhab/add-ons-maintainers
/bundles/org.openhab.binding.dominoswiss/ @Friesoch
/bundles/org.openhab.binding.doorbird/ @mhilbush
/bundles/org.openhab.binding.draytonwiser/ @andrew-schofield
/bundles/org.openhab.binding.dscalarm/ @RSStephens
Expand Down
5 changes: 5 additions & 0 deletions bom/openhab-addons/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,11 @@
<artifactId>org.openhab.binding.dmx</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.binding.dominoswiss</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.binding.doorbird</artifactId>
Expand Down
13 changes: 13 additions & 0 deletions bundles/org.openhab.binding.dominoswiss/NOTICE
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
This content is produced and maintained by the openHAB project.

* Project home: https://www.openhab.org

== Declared Project Licenses

This program and the accompanying materials are made available under the terms
of the Eclipse Public License 2.0 which is available at
https://www.eclipse.org/legal/epl-2.0/.

== Source Code

https://github.com/openhab/openhab-addons
100 changes: 100 additions & 0 deletions bundles/org.openhab.binding.dominoswiss/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# Dominoswiss Binding

This binding allows the control of rollershutters, using an eGate as gateway and Dominoswiss radio receivers.
The eGate-gateway is connected via ethernet to openHAB and sends its commands via radio to all rollershutters.
See https://www.brelag.com/ for more information.


## Supported Things

eGate: Dominoswiss eGate Server. The eGate is the gateway which sends the commands to the connected rollershutters. The bridge-type ID is egate.
Blind: represents one rollershutter, that can be controlled via eGate. The thing-type ID is blind.


## Discovery

Unfortunately no automatic discovery is possible due to protocol restrictions.
Every rollershutter must be known by eGate and can be called by it's number of storage-place on eGate gateway.



## Thing Configuration

The bridge "eGate" has one channel "getconfig" which returns the config of this bridge.
The eGate is configured with both an `ipAddress` and a port.

|Property|Default|Required|Description|
|--------|-------|--------|-----------|
|ipAddress|none|Yes|The IP or host name of the Dominoswiss EGate Serve|
|port|1318|Yes|Port interface of the Dominoswiss EGate Server|

```
Bridge dominoswiss:egate:myeGate "My eGate Server" @ "Home" [ ipAddres="localhost", port=5700 ]
```


The thing blind represents one blind on the eGate. Each blind is represented by an id set on your eGate.

```
Thing blind officeBlind "Office" @ "1stFloor" [ id="1"]
```

The blind-Thing has the following channels:

|Channel Type ID|Item Type|Description|
|---------------|---------|-----------|
|pulseUp|Rollershutter|sends one pulse up to this blind.|
|pulseDown|Rollershutter|sends one pulse down to this blind|
|continuousUp|Rollershutter|sends a continuous up to this blind. The blind will automatically stop as it is fully up.|
|continuousDown|Rollershutter|send a continous down to this blind. The blind will automatically stop as it is fully down.|
|stop|Rollershutter|stop the action of the blind. The command will be imadiatly sent to the blind.|
|shutter|Rollershutter|this is used to bind the channel to the shutter item. There are no further rules needed this channel will handel the up/down/stop commands. See example for usage.|
|tilt|Rollershutter|same as shutter, this will handel all up/down/stop - tilt commands to be used with the shutter-item.|
|tiltUp|Rollershutter|sends 3 pulse-up commands to this blind to tilt the blind. If your blind needs more than 3 pulse-up, create a rule yourself with three pluse-up commands. Between each pulse-up you should wait 150ms to let the command be processed.
|tiltDown|Rollershutter|sends 3 pulse-down commands to this blind to tilt the blind. If your blind needs more than 3 pulse-down, create a rule yourself with three pluse-down commands. Between each pulse-down you should wait 150ms to let the command be processed. |

## Full Example

Sample things file:

```
Bridge dominoswiss:egate:myeGate "My eGate Server" @ "Home" [ ipAddres="localhost", port="5500" ]
{
Thing blind officeBlind "Office" @ "1stFloor" [ id="1"]
Thing blind diningRoomBlind "Dining Room" @ "EG" [id="2"]
Thing blind kitchenBlind "Kitchen" @ "EG" [id="12"]
}
```

Sample items file:

```
Rollershutter OfficeBlindShutter "Office blind" <rollershutter> (g_blinds) { channel="dominoswiss:blind:myeGate:officeBlind:shutter"}

Rollershutter OfficeBlindShutterTilt "Tilt Office" <rollershutter> (g_blinds_tilt) { channel="dominoswiss:blind:meGgate:bueroBlind:tilt"}

```

Sample sitemap file

```
Switch item=OfficeBlindShutter
Switch item=OfficeBlindShutterTilt
```

Sample rule file

This example moves the blind of the office up as the sun passed 110 azimuth (so the sun is no longer shining directly into the office).

```
rule "OneSide up"
when
Item Azimuth changed
then
val azimuth = Math::round((Azimuth.state as DecimalType).intValue)
if (azimuth == 110)
{
OfficeBlindShutter.sendCommand(UP)
}
end
```
15 changes: 15 additions & 0 deletions bundles/org.openhab.binding.dominoswiss/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.addons.reactor.bundles</artifactId>
<version>3.2.0-SNAPSHOT</version>
</parent>
<artifactId>org.openhab.binding.dominoswiss</artifactId>

<name>openHAB Add-ons :: Bundles :: Dominoswiss Binding</name>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<features name="org.openhab.binding.dominoswiss-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.4.0">
<repository>mvn:org.openhab.core.features.karaf/org.openhab.core.features.karaf.openhab-core/${ohc.version}/xml/features</repository>

<feature name="openhab-binding-dominoswiss" description="dominoswiss Binding" version="${project.version}">
<feature>openhab-runtime-base</feature>
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.dominoswiss/${project.version}</bundle>
</feature>
</features>
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* Copyright (c) 2010-2021 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.dominoswiss.internal;

import org.eclipse.jdt.annotation.NonNullByDefault;

/**
* Configuration of a blind.
*
* @author Frieso Aeschbacher - Initial contribution
*/
@NonNullByDefault
public class BlindConfig {

/*
* The ID of that blind
*/
public String id = "";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
/**
* Copyright (c) 2010-2021 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.dominoswiss.internal;

import static org.openhab.binding.dominoswiss.internal.DominoswissBindingConstants.*;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.thing.Bridge;
import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingStatus;
import org.openhab.core.thing.ThingStatusDetail;
import org.openhab.core.thing.binding.BaseThingHandler;
import org.openhab.core.types.Command;
import org.openhab.core.types.RefreshType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* The {@link BlindHandler} is responsible for handling commands, which are
* sent to one of the channels.The class defines common constants, which are
* used across the whole binding
*
* @author Frieso Aeschbacher - Initial contribution
*/
@NonNullByDefault
public class BlindHandler extends BaseThingHandler {

private Logger logger = LoggerFactory.getLogger(BlindHandler.class);

private @Nullable EGateHandler dominoswissHandler;

private String id = "";

public BlindHandler(Thing thing) {
super(thing);
}

@Override
public void handleCommand(ChannelUID channelUID, Command command) {
logger.debug("Blind got command: {} and ChannelUID: {} ", command.toFullString(),
channelUID.getIdWithoutGroup());
Bridge bridge = getBridge();
EGateHandler localDominoswissHandler = dominoswissHandler;
if (bridge != null) {
localDominoswissHandler = (EGateHandler) bridge.getHandler();
}
if (localDominoswissHandler == null) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_UNINITIALIZED, "EGate not available");
logger.debug("Blind thing {} has no server configured, ignoring command: {}", getThing().getUID(), command);
return;
}

// Some of the code below is not designed to handle REFRESH
if (command == RefreshType.REFRESH) {
return;
}
switch (channelUID.getIdWithoutGroup()) {
case CHANNEL_PULSEUP:
if (command instanceof Number) {
localDominoswissHandler.pulseUp(id);
}
break;
case CHANNEL_PULSEDOWN:
if (command instanceof Number) {
localDominoswissHandler.pulseDown(id);
}
break;
case CHANNEL_CONTINOUSUP:
if (command instanceof Number) {
localDominoswissHandler.continuousUp(id);
}
break;
case CHANNEL_CONTINOUSDOWN:
if (command instanceof Number) {
localDominoswissHandler.continuousDown(id);
}
break;
case CHANNEL_STOP:
if (command instanceof Number) {
localDominoswissHandler.stop(id);
}
break;
case UP:
if (command instanceof Number) {
localDominoswissHandler.continuousUp(id);
}
break;
case DOWN:
if (command instanceof Number) {
localDominoswissHandler.continuousDown(id);
}
break;
case SHUTTER:
if (command.toFullString() == DOWN) {
localDominoswissHandler.continuousDown(id);
} else if (command.toFullString() == UP) {
localDominoswissHandler.continuousUp(id);
} else if (command.toFullString() == CHANNEL_STOP) {
localDominoswissHandler.stop(id);
} else {
logger.debug("Blind got command but nothing executed: {} and ChannelUID: {}",
command.toFullString(), channelUID.getIdWithoutGroup());
}

case TILTDOWN:
if (command instanceof Number) {
try {
localDominoswissHandler.tiltDown(id);
} catch (InterruptedException e) {
logger.debug("EGate tiltDown error: {} ", e.toString());
}
}
break;

case TILTUP:
if (command instanceof Number) {
try {
localDominoswissHandler.tiltUp(id);
} catch (InterruptedException e) {
logger.debug("EGate tiltUP error: {} ", e.toString());
}
}
break;

case SHUTTERTILT:
if (command.toFullString() == UP) {
localDominoswissHandler.pulseUp(id);
} else if (command.toFullString() == DOWN) {
localDominoswissHandler.pulseDown(id);
} else if (command.toFullString() == CHANNEL_STOP) {
localDominoswissHandler.stop(id);
} else {
logger.debug("Blind got command but nothing executed: {} and ChannelUID: {}",
command.toFullString(), channelUID.getIdWithoutGroup());
}

default:
break;
}
}

@Override
public void initialize() {
this.id = getConfig().as(BlindConfig.class).id;
Bridge bridge = getBridge();
if (bridge != null) {
dominoswissHandler = (EGateHandler) bridge.getHandler();
EGateHandler localDominoswissHandler = dominoswissHandler;
if (localDominoswissHandler != null) {
localDominoswissHandler.registerBlind(this.id, getThing().getUID());
try {
ThingStatus bridgeStatus = bridge.getStatus();
if (bridgeStatus == ThingStatus.ONLINE && getThing().getStatus() != ThingStatus.ONLINE) {
updateStatus(ThingStatus.ONLINE, ThingStatusDetail.NONE);
localDominoswissHandler = (EGateHandler) bridge.getHandler();
} else if (bridgeStatus == ThingStatus.OFFLINE) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE);
}
} catch (Exception e) {
logger.debug("Could not update ThingStatus ", e);
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE, e.toString());

}
}
}
}

/*
* Gets the ID of this Blind
*/
public String getID() {
return this.id;
}
}
Loading