Skip to content

Commit f466c88

Browse files
authored
[freeathomesystem] Initial contribution (openhab#13703)
Signed-off-by: Andras Uhrin <[email protected]>
1 parent 6db28f5 commit f466c88

38 files changed

+5761
-0
lines changed

Diff for: CODEOWNERS

+1
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@
114114
/bundles/org.openhab.binding.folderwatcher/ @goopilot
115115
/bundles/org.openhab.binding.folding/ @fa2k
116116
/bundles/org.openhab.binding.foobot/ @airboxlab @Hilbrand
117+
/bundles/org.openhab.binding.freeathomesystem/ @andrasU
117118
/bundles/org.openhab.binding.freebox/ @lolodomo
118119
/bundles/org.openhab.binding.freeboxos/ @clinique
119120
/bundles/org.openhab.binding.freecurrency/ @J-N-K

Diff for: bom/openhab-addons/pom.xml

+5
Original file line numberDiff line numberDiff line change
@@ -561,6 +561,11 @@
561561
<artifactId>org.openhab.binding.foobot</artifactId>
562562
<version>${project.version}</version>
563563
</dependency>
564+
<dependency>
565+
<groupId>org.openhab.addons.bundles</groupId>
566+
<artifactId>org.openhab.binding.freeathomesystem</artifactId>
567+
<version>${project.version}</version>
568+
</dependency>
564569
<dependency>
565570
<groupId>org.openhab.addons.bundles</groupId>
566571
<artifactId>org.openhab.binding.freebox</artifactId>

Diff for: bundles/org.openhab.binding.freeathomesystem/NOTICE

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
This content is produced and maintained by the openHAB project.
2+
3+
* Project home: https://www.openhab.org
4+
5+
== Declared Project Licenses
6+
7+
This program and the accompanying materials are made available under the terms
8+
of the Eclipse Public License 2.0 which is available at
9+
https://www.eclipse.org/legal/epl-2.0/.
10+
11+
== Source Code
12+
13+
https://github.com/openhab/openhab-addons
+143
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
# ABB/Busch-free@home Smart Home binding
2+
3+
openHAB ABB/Busch-free@home binding based on the offical free@home local API.
4+
5+
# Description
6+
7+
This binding allows you to connect your free@home Smart Home system from ABB / Busch-Jaeger to openHAB and to control and observe most of the components.
8+
It requires a System Access Point with version 2.6.1 or higher.
9+
10+
# Supported Devices
11+
12+
**Network Gateway / System Access Point**
13+
14+
- ABB / Busch-Jaeger System Access Point 2.0
15+
16+
**Sensors and Actuators**
17+
18+
- Switch Actuator Sensor with single and multiple channels (wired and wireless)
19+
- Dimming Actuator Sensor with single and multiple channels (wired, wireless and flex)
20+
- Motion detection with and without actuator (wired, wireless and flex)
21+
- Switch Actuator 4-channel
22+
- Dimming Actuator 4- and 6-channel
23+
- Door opener actuator
24+
- Door ring sensor
25+
- Hue devices (untested)
26+
27+
**Blinds and Windows**
28+
29+
- Shutter Actuator with single and multiple channels (wired and wireless)
30+
- Blind Actuator with single and multiple channels (wired and wireless)
31+
- Attic window actuator
32+
- Awning actuator
33+
34+
**Room Temperature Control**
35+
36+
- Room temperature controller master without fan
37+
- Room temperature controller master with fan
38+
- Room temperature controller slave
39+
40+
**Other devices** (e.g. movement detector, ring sensor and door opener)
41+
42+
- IP-touch panel (function: door opener, door ring sensor)
43+
- Virtual devices (e.g. virtual switch, RTC and detectors)
44+
45+
**Information about virtual devices**
46+
Virtual device in the free@home smart-home system needs continuous keep-alive signal otherwise the free@home device is marked as unresponsive.
47+
This keep-alive signal must be provided by a user script or set the TTL value of the virtual device to "-1" during the creation of the virtual device.
48+
49+
# Tested SysAP Versions
50+
51+
| Version | Supported |
52+
|---------|-----------|
53+
| 2.6.1 | yes |
54+
| 2.6.3 | yes |
55+
| 3.1.1 | yes |
56+
57+
# Setup / Installation
58+
59+
## Prerequisites
60+
61+
To make use of this Binding first the local free@home API has to be activated.
62+
The API is disabled by default.
63+
64+
1. Open the free@home next app
65+
1. Browse to "Settings ⇨ free@home settings ⇨ local API and activate the checkbox
66+
67+
## Setup and Discovery
68+
69+
The free@home bridge shall be added manually.
70+
Once it is added as a Thing with correct credentials, the scan of free@home devices will be possible.
71+
72+
## free@home components as openHAB Things
73+
74+
The ABB/Busch free@home system is calling its smart home components as free@home devices.
75+
The free@home system devices can have one or multiple channels depending the device's features.
76+
During the scanning process the openHAB binding will detect only the devices IDs.
77+
The device features will be detected at the point in time, when a openHAB Thing is created.
78+
At the of the creation the free@home binding will automatically create the relevant channels without any further configuration.
79+
If a free@home system device has multiple smart-home channels (e.g. 4x DIN/rail Actuator), the newly created Thing will get all relevant channels to operate all actuators existing inside the free@home device.
80+
81+
## Sensors and Actuators of free@home Devices as Things in openHAB
82+
83+
The free@home system supports sensors and actuators.
84+
The connection of sensors and actuators are done on the free@home system dashboard.
85+
If a Thing channel is a free@home device sensor channel, this channel is read only.
86+
87+
## Bridge Configuration
88+
89+
There are several settings for a bridge:
90+
91+
| Parameter | Description |
92+
|--------------------------|-----------------------------------------|
93+
| **ipAddress** (required) | Network address of the free@home SysAP |
94+
| **username** (required) | Valid user name for the free@home SysAP |
95+
| **password** (required) | Password of the user |
96+
97+
## Examples for .things
98+
99+
Things are all discovered automatically and visible on the openHAB UI after pushing the scan button
100+
101+
In order to manually configure a Thing:
102+
103+
```java
104+
Bridge freeathomesystem:bridge:mysysap [ ipAddress="...", username="...", password="..." ]
105+
{
106+
Thing device ABB700000001
107+
Thing device ABB700000012
108+
}
109+
```
110+
111+
The only parameter needed to create a Thing is the free@home device ID, which you can find as sticker on the device.
112+
The creation of the openHAB channels to operate the free@home device is happening automatically based on the device features detected online.
113+
114+
## Examples for .items
115+
116+
Sample for the free@home thermostat device
117+
118+
```java
119+
Switch Livingroom_Thermostat_Switch "Thermostat Siwtch" <temperature> (Livingroom) { channel="freeathomesystem:device:312095ad75:ABB700000001:ch0000#controller-on-off-request" }
120+
Switch LivingRoom_Thermostat_EcoOnOff "Thermostat Eco Activation" <switch> (Livingroom) { channel="freeathomesystem:device:312095ad75:ABB700000001:ch0000#eco-mode-on-off-request" }
121+
Number LivingRoom_Thermostat_MeasuredTemperature "Measured Temperature" <temperature> (Livingroom) ["Temperature"] { channel="freeathomesystem:device:312095ad75:ABB700000001:ch0000#measured-temperature" }
122+
Number LivingRoom_Thermostat_SetpointTemperature "Setpoint Temperature" <temperature> (Livingroom) ["Setpoint", "Temperature"] { channel="freeathomesystem:device:312095ad75:ABB700000001:ch0000#absolute-setpoint-temperature" }
123+
Number LivingRoom_ThermostatHeatingActive "Thermostat Heating Active" <temperature> (Livingroom) ["Status"] { channel="freeathomesystem:device:312095ad75:ABB700000001:ch0000#heating-active" }
124+
Number LivingRoom_ThermostatHeatingDemand "Thermostat Heating Demand" <temperature> (Livingroom) ["Status"] { channel="freeathomesystem:device:312095ad75:ABB700000001:ch0000#status-indication" }
125+
```
126+
127+
Sample for the free@home device for switch
128+
129+
```java
130+
Switch Livingroom_Switch "Livingroom Switch" <switch> (Livingroom) ["Light"] { channel="freeathomesystem:device:312095ad75:ABB700000012:ch0000#switch-on-off" }
131+
Switch Livingroom_Lamp "Livingroom Lamp" <switch> (Livingroom) ["Light"] { channel="freeathomesystem:device:312095ad75:ABB700000012:ch0006#switch-on-off" }
132+
Switch Livingroom_Aux "Livingroom Aux Switch" <switch> (Livingroom) ["Light"] { channel="freeathomesystem:device:312095ad75:ABB700000012:ch000b#switch-on-off" }
133+
```
134+
135+
# Communities
136+
137+
[openHAB community of this binding](https://community.openhab.org/t/abb-busch-jager-free-home-official-rest-api/141698)
138+
139+
[Busch-Jaeger Community](https://community.busch-jaeger.de/)
140+
141+
[free@home user group Facebook DE](https://www.facebook.com/groups/738242583015188)
142+
143+
[free@home user group Facebook EN](https://www.facebook.com/groups/452502972031360)

Diff for: bundles/org.openhab.binding.freeathomesystem/pom.xml

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4+
5+
<modelVersion>4.0.0</modelVersion>
6+
7+
<parent>
8+
<groupId>org.openhab.addons.bundles</groupId>
9+
<artifactId>org.openhab.addons.reactor.bundles</artifactId>
10+
<version>4.2.0-SNAPSHOT</version>
11+
</parent>
12+
13+
<artifactId>org.openhab.binding.freeathomesystem</artifactId>
14+
15+
<name>openHAB Add-ons :: Bundles :: FreeAtHomeSystem Binding</name>
16+
17+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<features name="org.openhab.binding.freeathomesystem-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.4.0">
3+
<repository>mvn:org.openhab.core.features.karaf/org.openhab.core.features.karaf.openhab-core/${ohc.version}/xml/features</repository>
4+
5+
<feature name="openhab-binding-freeathomesystem" description="FreeAtHomeSystem Binding" version="${project.version}">
6+
<feature>openhab-runtime-base</feature>
7+
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.freeathomesystem/${project.version}</bundle>
8+
</feature>
9+
</features>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/**
2+
* Copyright (c) 2010-2024 Contributors to the openHAB project
3+
*
4+
* See the NOTICE file(s) distributed with this work for additional
5+
* information.
6+
*
7+
* This program and the accompanying materials are made available under the
8+
* terms of the Eclipse Public License 2.0 which is available at
9+
* http://www.eclipse.org/legal/epl-2.0
10+
*
11+
* SPDX-License-Identifier: EPL-2.0
12+
*/
13+
package org.openhab.binding.freeathomesystem.internal;
14+
15+
import java.util.Set;
16+
17+
import org.eclipse.jdt.annotation.NonNullByDefault;
18+
import org.openhab.core.thing.ThingTypeUID;
19+
20+
/**
21+
* The {@link FreeAtHomeSystemBindingConstants} class defines common constants, which are
22+
* used across the whole binding.
23+
*
24+
* @author Andras Uhrin - Initial contribution
25+
*/
26+
@NonNullByDefault
27+
public class FreeAtHomeSystemBindingConstants {
28+
29+
public static final String CONFIG_DESCRIPTION_URI_THING_PREFIX = "thing-type";
30+
31+
public static final String BINDING_ID = "freeathomesystem";
32+
33+
// List of all Thing Type UIDs
34+
public static final String BRIDGE_TYPE_ID = "gateway";
35+
public static final String DEVICE_TYPE_ID = "device";
36+
37+
// List of all Thing Type UIDs
38+
public static final ThingTypeUID BRIDGE_TYPE_UID = new ThingTypeUID(BINDING_ID, BRIDGE_TYPE_ID);
39+
public static final ThingTypeUID DEVICE_TYPE_UID = new ThingTypeUID(BINDING_ID, DEVICE_TYPE_ID);
40+
41+
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Set.of(BRIDGE_TYPE_UID, DEVICE_TYPE_UID);
42+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
/**
2+
* Copyright (c) 2010-2024 Contributors to the openHAB project
3+
*
4+
* See the NOTICE file(s) distributed with this work for additional
5+
* information.
6+
*
7+
* This program and the accompanying materials are made available under the
8+
* terms of the Eclipse Public License 2.0 which is available at
9+
* http://www.eclipse.org/legal/epl-2.0
10+
*
11+
* SPDX-License-Identifier: EPL-2.0
12+
*/
13+
package org.openhab.binding.freeathomesystem.internal;
14+
15+
import java.time.Instant;
16+
import java.util.HashMap;
17+
import java.util.List;
18+
import java.util.Map;
19+
import java.util.Set;
20+
import java.util.concurrent.ScheduledFuture;
21+
import java.util.concurrent.TimeUnit;
22+
23+
import org.eclipse.jdt.annotation.NonNullByDefault;
24+
import org.eclipse.jdt.annotation.Nullable;
25+
import org.openhab.binding.freeathomesystem.internal.datamodel.FreeAtHomeDeviceDescription;
26+
import org.openhab.binding.freeathomesystem.internal.handler.FreeAtHomeBridgeHandler;
27+
import org.openhab.binding.freeathomesystem.internal.util.FreeAtHomeHttpCommunicationException;
28+
import org.openhab.core.config.discovery.AbstractThingHandlerDiscoveryService;
29+
import org.openhab.core.config.discovery.DiscoveryResult;
30+
import org.openhab.core.config.discovery.DiscoveryResultBuilder;
31+
import org.openhab.core.thing.ThingTypeUID;
32+
import org.openhab.core.thing.ThingUID;
33+
import org.slf4j.Logger;
34+
import org.slf4j.LoggerFactory;
35+
36+
/**
37+
* The {@link FreeAtHomeSystemDiscoveryService} is responsible for performing discovery of things
38+
*
39+
* @author Andras Uhrin - Initial contribution
40+
*/
41+
@NonNullByDefault
42+
public class FreeAtHomeSystemDiscoveryService extends AbstractThingHandlerDiscoveryService<FreeAtHomeBridgeHandler> {
43+
44+
private final Logger logger = LoggerFactory.getLogger(FreeAtHomeSystemDiscoveryService.class);
45+
private @Nullable ScheduledFuture<?> backgroundDiscoveryJob = null;
46+
47+
private static final long BACKGROUND_DISCOVERY_DELAY = 1L;
48+
private boolean isScanTerminated;
49+
50+
Runnable runnable = new Runnable() {
51+
@Override
52+
public void run() {
53+
ThingUID bridgeUID = thingHandler.getThing().getUID();
54+
55+
List<String> deviceList;
56+
57+
try {
58+
deviceList = thingHandler.getDeviceDeviceList();
59+
60+
for (int i = 0; (i < deviceList.size()) && !isScanTerminated; i++) {
61+
FreeAtHomeDeviceDescription device = thingHandler.getFreeatHomeDeviceDescription(deviceList.get(i));
62+
63+
ThingUID uid = new ThingUID(FreeAtHomeSystemBindingConstants.DEVICE_TYPE_UID, bridgeUID,
64+
device.deviceId);
65+
Map<String, Object> properties = new HashMap<>(1);
66+
properties.put("deviceId", device.deviceId);
67+
properties.put("interface", device.interfaceType);
68+
69+
String deviceLabel = device.deviceLabel;
70+
71+
DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(uid).withLabel(deviceLabel)
72+
.withRepresentationProperty("deviceId").withBridge(bridgeUID).withProperties(properties)
73+
.build();
74+
75+
thingDiscovered(discoveryResult);
76+
77+
logger.debug("Thing discovered - DeviceId: {} - Device label: {}", device.getDeviceId(),
78+
device.getDeviceLabel());
79+
}
80+
81+
stopScan();
82+
} catch (FreeAtHomeHttpCommunicationException e) {
83+
logger.debug("Communication error in device discovery with the bridge: {}",
84+
thingHandler.getThing().getLabel());
85+
} catch (RuntimeException e) {
86+
logger.debug("Scanning interrupted");
87+
}
88+
}
89+
};
90+
91+
public FreeAtHomeSystemDiscoveryService(int timeout) {
92+
super(FreeAtHomeBridgeHandler.class, FreeAtHomeSystemBindingConstants.SUPPORTED_THING_TYPES_UIDS, timeout,
93+
false);
94+
}
95+
96+
public FreeAtHomeSystemDiscoveryService() {
97+
this(90);
98+
}
99+
100+
@Override
101+
public Set<ThingTypeUID> getSupportedThingTypes() {
102+
return Set.of(FreeAtHomeSystemBindingConstants.BRIDGE_TYPE_UID);
103+
}
104+
105+
@Override
106+
protected void startScan() {
107+
if (backgroundDiscoveryJob == null) {
108+
this.removeOlderResults(Instant.now().toEpochMilli());
109+
110+
isScanTerminated = false;
111+
backgroundDiscoveryJob = scheduler.schedule(runnable, BACKGROUND_DISCOVERY_DELAY, TimeUnit.SECONDS);
112+
}
113+
}
114+
115+
@Override
116+
protected synchronized void stopScan() {
117+
super.stopScan();
118+
119+
isScanTerminated = true;
120+
121+
ScheduledFuture<?> localDiscoveryJob = backgroundDiscoveryJob;
122+
123+
if (localDiscoveryJob != null) {
124+
localDiscoveryJob.cancel(true);
125+
}
126+
127+
backgroundDiscoveryJob = null;
128+
129+
removeOlderResults(Instant.now().toEpochMilli());
130+
}
131+
132+
@Override
133+
public void deactivate() {
134+
removeOlderResults(Instant.now().toEpochMilli());
135+
}
136+
}

0 commit comments

Comments
 (0)