mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-01-10 15:11:59 +01:00
[freeathomesystem] Initial contribution (#13703)
Signed-off-by: Andras Uhrin <andras.uhrin@gmail.com>
This commit is contained in:
parent
6db28f5b46
commit
f466c88406
@ -114,6 +114,7 @@
|
|||||||
/bundles/org.openhab.binding.folderwatcher/ @goopilot
|
/bundles/org.openhab.binding.folderwatcher/ @goopilot
|
||||||
/bundles/org.openhab.binding.folding/ @fa2k
|
/bundles/org.openhab.binding.folding/ @fa2k
|
||||||
/bundles/org.openhab.binding.foobot/ @airboxlab @Hilbrand
|
/bundles/org.openhab.binding.foobot/ @airboxlab @Hilbrand
|
||||||
|
/bundles/org.openhab.binding.freeathomesystem/ @andrasU
|
||||||
/bundles/org.openhab.binding.freebox/ @lolodomo
|
/bundles/org.openhab.binding.freebox/ @lolodomo
|
||||||
/bundles/org.openhab.binding.freeboxos/ @clinique
|
/bundles/org.openhab.binding.freeboxos/ @clinique
|
||||||
/bundles/org.openhab.binding.freecurrency/ @J-N-K
|
/bundles/org.openhab.binding.freecurrency/ @J-N-K
|
||||||
|
@ -561,6 +561,11 @@
|
|||||||
<artifactId>org.openhab.binding.foobot</artifactId>
|
<artifactId>org.openhab.binding.foobot</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.openhab.addons.bundles</groupId>
|
||||||
|
<artifactId>org.openhab.binding.freeathomesystem</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.openhab.addons.bundles</groupId>
|
<groupId>org.openhab.addons.bundles</groupId>
|
||||||
<artifactId>org.openhab.binding.freebox</artifactId>
|
<artifactId>org.openhab.binding.freebox</artifactId>
|
||||||
|
13
bundles/org.openhab.binding.freeathomesystem/NOTICE
Normal file
13
bundles/org.openhab.binding.freeathomesystem/NOTICE
Normal file
@ -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
|
143
bundles/org.openhab.binding.freeathomesystem/README.md
Normal file
143
bundles/org.openhab.binding.freeathomesystem/README.md
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
# ABB/Busch-free@home Smart Home binding
|
||||||
|
|
||||||
|
openHAB ABB/Busch-free@home binding based on the offical free@home local API.
|
||||||
|
|
||||||
|
# Description
|
||||||
|
|
||||||
|
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.
|
||||||
|
It requires a System Access Point with version 2.6.1 or higher.
|
||||||
|
|
||||||
|
# Supported Devices
|
||||||
|
|
||||||
|
**Network Gateway / System Access Point**
|
||||||
|
|
||||||
|
- ABB / Busch-Jaeger System Access Point 2.0
|
||||||
|
|
||||||
|
**Sensors and Actuators**
|
||||||
|
|
||||||
|
- Switch Actuator Sensor with single and multiple channels (wired and wireless)
|
||||||
|
- Dimming Actuator Sensor with single and multiple channels (wired, wireless and flex)
|
||||||
|
- Motion detection with and without actuator (wired, wireless and flex)
|
||||||
|
- Switch Actuator 4-channel
|
||||||
|
- Dimming Actuator 4- and 6-channel
|
||||||
|
- Door opener actuator
|
||||||
|
- Door ring sensor
|
||||||
|
- Hue devices (untested)
|
||||||
|
|
||||||
|
**Blinds and Windows**
|
||||||
|
|
||||||
|
- Shutter Actuator with single and multiple channels (wired and wireless)
|
||||||
|
- Blind Actuator with single and multiple channels (wired and wireless)
|
||||||
|
- Attic window actuator
|
||||||
|
- Awning actuator
|
||||||
|
|
||||||
|
**Room Temperature Control**
|
||||||
|
|
||||||
|
- Room temperature controller master without fan
|
||||||
|
- Room temperature controller master with fan
|
||||||
|
- Room temperature controller slave
|
||||||
|
|
||||||
|
**Other devices** (e.g. movement detector, ring sensor and door opener)
|
||||||
|
|
||||||
|
- IP-touch panel (function: door opener, door ring sensor)
|
||||||
|
- Virtual devices (e.g. virtual switch, RTC and detectors)
|
||||||
|
|
||||||
|
**Information about virtual devices**
|
||||||
|
Virtual device in the free@home smart-home system needs continuous keep-alive signal otherwise the free@home device is marked as unresponsive.
|
||||||
|
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.
|
||||||
|
|
||||||
|
# Tested SysAP Versions
|
||||||
|
|
||||||
|
| Version | Supported |
|
||||||
|
|---------|-----------|
|
||||||
|
| 2.6.1 | yes |
|
||||||
|
| 2.6.3 | yes |
|
||||||
|
| 3.1.1 | yes |
|
||||||
|
|
||||||
|
# Setup / Installation
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
To make use of this Binding first the local free@home API has to be activated.
|
||||||
|
The API is disabled by default.
|
||||||
|
|
||||||
|
1. Open the free@home next app
|
||||||
|
1. Browse to "Settings ⇨ free@home settings ⇨ local API and activate the checkbox
|
||||||
|
|
||||||
|
## Setup and Discovery
|
||||||
|
|
||||||
|
The free@home bridge shall be added manually.
|
||||||
|
Once it is added as a Thing with correct credentials, the scan of free@home devices will be possible.
|
||||||
|
|
||||||
|
## free@home components as openHAB Things
|
||||||
|
|
||||||
|
The ABB/Busch free@home system is calling its smart home components as free@home devices.
|
||||||
|
The free@home system devices can have one or multiple channels depending the device's features.
|
||||||
|
During the scanning process the openHAB binding will detect only the devices IDs.
|
||||||
|
The device features will be detected at the point in time, when a openHAB Thing is created.
|
||||||
|
At the of the creation the free@home binding will automatically create the relevant channels without any further configuration.
|
||||||
|
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.
|
||||||
|
|
||||||
|
## Sensors and Actuators of free@home Devices as Things in openHAB
|
||||||
|
|
||||||
|
The free@home system supports sensors and actuators.
|
||||||
|
The connection of sensors and actuators are done on the free@home system dashboard.
|
||||||
|
If a Thing channel is a free@home device sensor channel, this channel is read only.
|
||||||
|
|
||||||
|
## Bridge Configuration
|
||||||
|
|
||||||
|
There are several settings for a bridge:
|
||||||
|
|
||||||
|
| Parameter | Description |
|
||||||
|
|--------------------------|-----------------------------------------|
|
||||||
|
| **ipAddress** (required) | Network address of the free@home SysAP |
|
||||||
|
| **username** (required) | Valid user name for the free@home SysAP |
|
||||||
|
| **password** (required) | Password of the user |
|
||||||
|
|
||||||
|
## Examples for .things
|
||||||
|
|
||||||
|
Things are all discovered automatically and visible on the openHAB UI after pushing the scan button
|
||||||
|
|
||||||
|
In order to manually configure a Thing:
|
||||||
|
|
||||||
|
```java
|
||||||
|
Bridge freeathomesystem:bridge:mysysap [ ipAddress="...", username="...", password="..." ]
|
||||||
|
{
|
||||||
|
Thing device ABB700000001
|
||||||
|
Thing device ABB700000012
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The only parameter needed to create a Thing is the free@home device ID, which you can find as sticker on the device.
|
||||||
|
The creation of the openHAB channels to operate the free@home device is happening automatically based on the device features detected online.
|
||||||
|
|
||||||
|
## Examples for .items
|
||||||
|
|
||||||
|
Sample for the free@home thermostat device
|
||||||
|
|
||||||
|
```java
|
||||||
|
Switch Livingroom_Thermostat_Switch "Thermostat Siwtch" <temperature> (Livingroom) { channel="freeathomesystem:device:312095ad75:ABB700000001:ch0000#controller-on-off-request" }
|
||||||
|
Switch LivingRoom_Thermostat_EcoOnOff "Thermostat Eco Activation" <switch> (Livingroom) { channel="freeathomesystem:device:312095ad75:ABB700000001:ch0000#eco-mode-on-off-request" }
|
||||||
|
Number LivingRoom_Thermostat_MeasuredTemperature "Measured Temperature" <temperature> (Livingroom) ["Temperature"] { channel="freeathomesystem:device:312095ad75:ABB700000001:ch0000#measured-temperature" }
|
||||||
|
Number LivingRoom_Thermostat_SetpointTemperature "Setpoint Temperature" <temperature> (Livingroom) ["Setpoint", "Temperature"] { channel="freeathomesystem:device:312095ad75:ABB700000001:ch0000#absolute-setpoint-temperature" }
|
||||||
|
Number LivingRoom_ThermostatHeatingActive "Thermostat Heating Active" <temperature> (Livingroom) ["Status"] { channel="freeathomesystem:device:312095ad75:ABB700000001:ch0000#heating-active" }
|
||||||
|
Number LivingRoom_ThermostatHeatingDemand "Thermostat Heating Demand" <temperature> (Livingroom) ["Status"] { channel="freeathomesystem:device:312095ad75:ABB700000001:ch0000#status-indication" }
|
||||||
|
```
|
||||||
|
|
||||||
|
Sample for the free@home device for switch
|
||||||
|
|
||||||
|
```java
|
||||||
|
Switch Livingroom_Switch "Livingroom Switch" <switch> (Livingroom) ["Light"] { channel="freeathomesystem:device:312095ad75:ABB700000012:ch0000#switch-on-off" }
|
||||||
|
Switch Livingroom_Lamp "Livingroom Lamp" <switch> (Livingroom) ["Light"] { channel="freeathomesystem:device:312095ad75:ABB700000012:ch0006#switch-on-off" }
|
||||||
|
Switch Livingroom_Aux "Livingroom Aux Switch" <switch> (Livingroom) ["Light"] { channel="freeathomesystem:device:312095ad75:ABB700000012:ch000b#switch-on-off" }
|
||||||
|
```
|
||||||
|
|
||||||
|
# Communities
|
||||||
|
|
||||||
|
[openHAB community of this binding](https://community.openhab.org/t/abb-busch-jager-free-home-official-rest-api/141698)
|
||||||
|
|
||||||
|
[Busch-Jaeger Community](https://community.busch-jaeger.de/)
|
||||||
|
|
||||||
|
[free@home user group Facebook DE](https://www.facebook.com/groups/738242583015188)
|
||||||
|
|
||||||
|
[free@home user group Facebook EN](https://www.facebook.com/groups/452502972031360)
|
17
bundles/org.openhab.binding.freeathomesystem/pom.xml
Normal file
17
bundles/org.openhab.binding.freeathomesystem/pom.xml
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?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 https://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>4.2.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>org.openhab.binding.freeathomesystem</artifactId>
|
||||||
|
|
||||||
|
<name>openHAB Add-ons :: Bundles :: FreeAtHomeSystem Binding</name>
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<features name="org.openhab.binding.freeathomesystem-${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-freeathomesystem" description="FreeAtHomeSystem Binding" version="${project.version}">
|
||||||
|
<feature>openhab-runtime-base</feature>
|
||||||
|
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.freeathomesystem/${project.version}</bundle>
|
||||||
|
</feature>
|
||||||
|
</features>
|
@ -0,0 +1,42 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2024 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.freeathomesystem.internal;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.openhab.core.thing.ThingTypeUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link FreeAtHomeSystemBindingConstants} class defines common constants, which are
|
||||||
|
* used across the whole binding.
|
||||||
|
*
|
||||||
|
* @author Andras Uhrin - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class FreeAtHomeSystemBindingConstants {
|
||||||
|
|
||||||
|
public static final String CONFIG_DESCRIPTION_URI_THING_PREFIX = "thing-type";
|
||||||
|
|
||||||
|
public static final String BINDING_ID = "freeathomesystem";
|
||||||
|
|
||||||
|
// List of all Thing Type UIDs
|
||||||
|
public static final String BRIDGE_TYPE_ID = "gateway";
|
||||||
|
public static final String DEVICE_TYPE_ID = "device";
|
||||||
|
|
||||||
|
// List of all Thing Type UIDs
|
||||||
|
public static final ThingTypeUID BRIDGE_TYPE_UID = new ThingTypeUID(BINDING_ID, BRIDGE_TYPE_ID);
|
||||||
|
public static final ThingTypeUID DEVICE_TYPE_UID = new ThingTypeUID(BINDING_ID, DEVICE_TYPE_ID);
|
||||||
|
|
||||||
|
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Set.of(BRIDGE_TYPE_UID, DEVICE_TYPE_UID);
|
||||||
|
}
|
@ -0,0 +1,136 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2024 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.freeathomesystem.internal;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ScheduledFuture;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
import org.openhab.binding.freeathomesystem.internal.datamodel.FreeAtHomeDeviceDescription;
|
||||||
|
import org.openhab.binding.freeathomesystem.internal.handler.FreeAtHomeBridgeHandler;
|
||||||
|
import org.openhab.binding.freeathomesystem.internal.util.FreeAtHomeHttpCommunicationException;
|
||||||
|
import org.openhab.core.config.discovery.AbstractThingHandlerDiscoveryService;
|
||||||
|
import org.openhab.core.config.discovery.DiscoveryResult;
|
||||||
|
import org.openhab.core.config.discovery.DiscoveryResultBuilder;
|
||||||
|
import org.openhab.core.thing.ThingTypeUID;
|
||||||
|
import org.openhab.core.thing.ThingUID;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link FreeAtHomeSystemDiscoveryService} is responsible for performing discovery of things
|
||||||
|
*
|
||||||
|
* @author Andras Uhrin - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class FreeAtHomeSystemDiscoveryService extends AbstractThingHandlerDiscoveryService<FreeAtHomeBridgeHandler> {
|
||||||
|
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(FreeAtHomeSystemDiscoveryService.class);
|
||||||
|
private @Nullable ScheduledFuture<?> backgroundDiscoveryJob = null;
|
||||||
|
|
||||||
|
private static final long BACKGROUND_DISCOVERY_DELAY = 1L;
|
||||||
|
private boolean isScanTerminated;
|
||||||
|
|
||||||
|
Runnable runnable = new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
ThingUID bridgeUID = thingHandler.getThing().getUID();
|
||||||
|
|
||||||
|
List<String> deviceList;
|
||||||
|
|
||||||
|
try {
|
||||||
|
deviceList = thingHandler.getDeviceDeviceList();
|
||||||
|
|
||||||
|
for (int i = 0; (i < deviceList.size()) && !isScanTerminated; i++) {
|
||||||
|
FreeAtHomeDeviceDescription device = thingHandler.getFreeatHomeDeviceDescription(deviceList.get(i));
|
||||||
|
|
||||||
|
ThingUID uid = new ThingUID(FreeAtHomeSystemBindingConstants.DEVICE_TYPE_UID, bridgeUID,
|
||||||
|
device.deviceId);
|
||||||
|
Map<String, Object> properties = new HashMap<>(1);
|
||||||
|
properties.put("deviceId", device.deviceId);
|
||||||
|
properties.put("interface", device.interfaceType);
|
||||||
|
|
||||||
|
String deviceLabel = device.deviceLabel;
|
||||||
|
|
||||||
|
DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(uid).withLabel(deviceLabel)
|
||||||
|
.withRepresentationProperty("deviceId").withBridge(bridgeUID).withProperties(properties)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
thingDiscovered(discoveryResult);
|
||||||
|
|
||||||
|
logger.debug("Thing discovered - DeviceId: {} - Device label: {}", device.getDeviceId(),
|
||||||
|
device.getDeviceLabel());
|
||||||
|
}
|
||||||
|
|
||||||
|
stopScan();
|
||||||
|
} catch (FreeAtHomeHttpCommunicationException e) {
|
||||||
|
logger.debug("Communication error in device discovery with the bridge: {}",
|
||||||
|
thingHandler.getThing().getLabel());
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
logger.debug("Scanning interrupted");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public FreeAtHomeSystemDiscoveryService(int timeout) {
|
||||||
|
super(FreeAtHomeBridgeHandler.class, FreeAtHomeSystemBindingConstants.SUPPORTED_THING_TYPES_UIDS, timeout,
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FreeAtHomeSystemDiscoveryService() {
|
||||||
|
this(90);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<ThingTypeUID> getSupportedThingTypes() {
|
||||||
|
return Set.of(FreeAtHomeSystemBindingConstants.BRIDGE_TYPE_UID);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void startScan() {
|
||||||
|
if (backgroundDiscoveryJob == null) {
|
||||||
|
this.removeOlderResults(Instant.now().toEpochMilli());
|
||||||
|
|
||||||
|
isScanTerminated = false;
|
||||||
|
backgroundDiscoveryJob = scheduler.schedule(runnable, BACKGROUND_DISCOVERY_DELAY, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected synchronized void stopScan() {
|
||||||
|
super.stopScan();
|
||||||
|
|
||||||
|
isScanTerminated = true;
|
||||||
|
|
||||||
|
ScheduledFuture<?> localDiscoveryJob = backgroundDiscoveryJob;
|
||||||
|
|
||||||
|
if (localDiscoveryJob != null) {
|
||||||
|
localDiscoveryJob.cancel(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
backgroundDiscoveryJob = null;
|
||||||
|
|
||||||
|
removeOlderResults(Instant.now().toEpochMilli());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deactivate() {
|
||||||
|
removeOlderResults(Instant.now().toEpochMilli());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,116 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2024 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.freeathomesystem.internal;
|
||||||
|
|
||||||
|
import static org.openhab.binding.freeathomesystem.internal.FreeAtHomeSystemBindingConstants.*;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
import org.eclipse.jetty.client.HttpClient;
|
||||||
|
import org.openhab.binding.freeathomesystem.internal.handler.FreeAtHomeBridgeHandler;
|
||||||
|
import org.openhab.binding.freeathomesystem.internal.handler.FreeAtHomeDeviceHandler;
|
||||||
|
import org.openhab.binding.freeathomesystem.internal.type.FreeAtHomeChannelTypeProvider;
|
||||||
|
import org.openhab.binding.freeathomesystem.internal.type.FreeAtHomeThingTypeProvider;
|
||||||
|
import org.openhab.core.i18n.LocaleProvider;
|
||||||
|
import org.openhab.core.i18n.TranslationProvider;
|
||||||
|
import org.openhab.core.io.net.http.HttpClientFactory;
|
||||||
|
import org.openhab.core.thing.Bridge;
|
||||||
|
import org.openhab.core.thing.Thing;
|
||||||
|
import org.openhab.core.thing.ThingTypeUID;
|
||||||
|
import org.openhab.core.thing.binding.BaseThingHandlerFactory;
|
||||||
|
import org.openhab.core.thing.binding.ThingHandler;
|
||||||
|
import org.openhab.core.thing.binding.ThingHandlerFactory;
|
||||||
|
import org.osgi.service.component.ComponentContext;
|
||||||
|
import org.osgi.service.component.annotations.Activate;
|
||||||
|
import org.osgi.service.component.annotations.Component;
|
||||||
|
import org.osgi.service.component.annotations.Deactivate;
|
||||||
|
import org.osgi.service.component.annotations.Reference;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link FreeAtHomeSystemHandlerFactory} is responsible for creating things and thing
|
||||||
|
* handlers.
|
||||||
|
*
|
||||||
|
* @author Andras Uhrin - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
@Component(configurationPid = "binding.freeathomesystem", service = ThingHandlerFactory.class)
|
||||||
|
public class FreeAtHomeSystemHandlerFactory extends BaseThingHandlerFactory {
|
||||||
|
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(FreeAtHomeSystemHandlerFactory.class);
|
||||||
|
|
||||||
|
private final HttpClient httpClient;
|
||||||
|
private final FreeAtHomeChannelTypeProvider channelTypeProvider;
|
||||||
|
private final TranslationProvider i18nProvider;
|
||||||
|
private final LocaleProvider localeProvider;
|
||||||
|
|
||||||
|
@Activate
|
||||||
|
public FreeAtHomeSystemHandlerFactory(@Reference FreeAtHomeThingTypeProvider thingTypeProvider,
|
||||||
|
@Reference FreeAtHomeChannelTypeProvider channelTypeProvider, @Reference TranslationProvider i18nProvider,
|
||||||
|
@Reference LocaleProvider localeProvider, @Reference HttpClientFactory httpClientFactory,
|
||||||
|
ComponentContext componentContext) {
|
||||||
|
super.activate(componentContext);
|
||||||
|
this.channelTypeProvider = channelTypeProvider;
|
||||||
|
this.i18nProvider = i18nProvider;
|
||||||
|
this.localeProvider = localeProvider;
|
||||||
|
|
||||||
|
// create httpClient
|
||||||
|
httpClient = httpClientFactory.createHttpClient(FreeAtHomeSystemBindingConstants.BINDING_ID);
|
||||||
|
|
||||||
|
// Configure client
|
||||||
|
httpClient.setFollowRedirects(false);
|
||||||
|
httpClient.setMaxConnectionsPerDestination(1);
|
||||||
|
httpClient.setMaxRequestsQueuedPerDestination(50);
|
||||||
|
|
||||||
|
// Set timeouts
|
||||||
|
httpClient.setIdleTimeout(-1);
|
||||||
|
httpClient.setConnectTimeout(5000);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Start HttpClient.
|
||||||
|
httpClient.start();
|
||||||
|
} catch (Exception ex) {
|
||||||
|
logger.error("Could not create HttpClient: {}", ex.getMessage());
|
||||||
|
|
||||||
|
throw new IllegalStateException("Could not create HttpClient", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deactivate
|
||||||
|
public void deactivate() {
|
||||||
|
try {
|
||||||
|
httpClient.stop();
|
||||||
|
} catch (Exception ex) {
|
||||||
|
logger.warn("Failed to stop HttpClient: {}", ex.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
|
||||||
|
return SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected @Nullable ThingHandler createHandler(Thing thing) {
|
||||||
|
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
|
||||||
|
|
||||||
|
if (BRIDGE_TYPE_UID.equals(thingTypeUID)) {
|
||||||
|
return new FreeAtHomeBridgeHandler((Bridge) thing, httpClient);
|
||||||
|
} else if (DEVICE_TYPE_UID.equals(thingTypeUID)) {
|
||||||
|
return new FreeAtHomeDeviceHandler(thing, channelTypeProvider, i18nProvider, localeProvider);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2024 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.freeathomesystem.internal.configuration;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link FreeAtHomeBridgeHandlerConfiguration} class contains fields mapping thing configuration parameters.
|
||||||
|
*
|
||||||
|
* @author Andras Uhrin - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class FreeAtHomeBridgeHandlerConfiguration {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bridgeconfiguration parameter.
|
||||||
|
*/
|
||||||
|
public String ipAddress = "";
|
||||||
|
public String username = "";
|
||||||
|
public String password = "";
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2024 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.freeathomesystem.internal.configuration;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link FreeAtHomeDeviceHandlerConfiguration} class contains fields mapping device configuration parameters.
|
||||||
|
*
|
||||||
|
* @author Andras Uhrin - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class FreeAtHomeDeviceHandlerConfiguration {
|
||||||
|
public String deviceId = "";
|
||||||
|
}
|
@ -0,0 +1,116 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2024 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.freeathomesystem.internal.datamodel;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Andras Uhrin - Initial contribution
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class FreeAtHomeDatapoint {
|
||||||
|
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(FreeAtHomeDatapoint.class);
|
||||||
|
|
||||||
|
enum DatapointDirection {
|
||||||
|
UNKNOWN,
|
||||||
|
INPUT,
|
||||||
|
OUTPUT,
|
||||||
|
INPUTOUTPUT,
|
||||||
|
INPUT_AS_OUTPUT
|
||||||
|
};
|
||||||
|
|
||||||
|
public String channelId = "";
|
||||||
|
private String datapointId = "";
|
||||||
|
|
||||||
|
DatapointDirection searchForDatapoint(DatapointDirection direction, int neededPairingIDFunction, String channelId,
|
||||||
|
JsonObject jsonObjectOfChannel) {
|
||||||
|
DatapointDirection resultingDirection = DatapointDirection.UNKNOWN;
|
||||||
|
boolean foundId = false;
|
||||||
|
JsonObject localDatapoints = null;
|
||||||
|
|
||||||
|
switch (direction) {
|
||||||
|
case INPUT: {
|
||||||
|
localDatapoints = jsonObjectOfChannel.getAsJsonObject("inputs");
|
||||||
|
resultingDirection = DatapointDirection.INPUT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case INPUT_AS_OUTPUT: {
|
||||||
|
localDatapoints = jsonObjectOfChannel.getAsJsonObject("inputs");
|
||||||
|
resultingDirection = DatapointDirection.OUTPUT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case OUTPUT: {
|
||||||
|
localDatapoints = jsonObjectOfChannel.getAsJsonObject("outputs");
|
||||||
|
resultingDirection = DatapointDirection.OUTPUT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
localDatapoints = jsonObjectOfChannel.getAsJsonObject("outputs");
|
||||||
|
resultingDirection = DatapointDirection.OUTPUT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<String> keys = localDatapoints.keySet();
|
||||||
|
|
||||||
|
Iterator<String> iter = keys.iterator();
|
||||||
|
|
||||||
|
// Scan datapoints for pairingID IDs
|
||||||
|
while (iter.hasNext() && !foundId) {
|
||||||
|
String datapointId = iter.next();
|
||||||
|
|
||||||
|
JsonObject datapointJsonObject = localDatapoints.getAsJsonObject(datapointId);
|
||||||
|
|
||||||
|
int pairingIDFunction = datapointJsonObject.get("pairingID").getAsInt();
|
||||||
|
|
||||||
|
if (pairingIDFunction == neededPairingIDFunction) {
|
||||||
|
this.channelId = channelId;
|
||||||
|
this.datapointId = datapointId;
|
||||||
|
|
||||||
|
logger.debug("Datapoint is found - channel {} - datapoint {}", this.channelId, this.datapointId);
|
||||||
|
|
||||||
|
foundId = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// id not found, add dummy
|
||||||
|
if (!foundId) {
|
||||||
|
this.channelId = "";
|
||||||
|
this.datapointId = "";
|
||||||
|
resultingDirection = DatapointDirection.UNKNOWN;
|
||||||
|
|
||||||
|
logger.debug("Needed datapoint is not found - channel {} - pairingId {}", channelId,
|
||||||
|
neededPairingIDFunction);
|
||||||
|
}
|
||||||
|
|
||||||
|
return resultingDirection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getChannelIdforDatapoint() {
|
||||||
|
return channelId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDatapointId() {
|
||||||
|
return datapointId;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,262 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2024 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.freeathomesystem.internal.datamodel;
|
||||||
|
|
||||||
|
import static org.openhab.binding.freeathomesystem.internal.datamodel.FreeAtHomeDatapoint.*;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
import org.openhab.binding.freeathomesystem.internal.util.FreeAtHomeGeneralException;
|
||||||
|
import org.openhab.binding.freeathomesystem.internal.util.PidTranslationUtils;
|
||||||
|
import org.openhab.binding.freeathomesystem.internal.valuestateconverter.BooleanValueStateConverter;
|
||||||
|
import org.openhab.binding.freeathomesystem.internal.valuestateconverter.DecimalValueStateConverter;
|
||||||
|
import org.openhab.binding.freeathomesystem.internal.valuestateconverter.ShuttercontrolValueStateConverter;
|
||||||
|
import org.openhab.binding.freeathomesystem.internal.valuestateconverter.ValueStateConverter;
|
||||||
|
import org.openhab.core.library.CoreItemFactory;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Andras Uhrin - Initial contribution
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class FreeAtHomeDatapointGroup {
|
||||||
|
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(FreeAtHomeDatapointGroup.class);
|
||||||
|
|
||||||
|
public enum DatapointGroupDirection {
|
||||||
|
UNDEFINED,
|
||||||
|
INPUT,
|
||||||
|
OUTPUT,
|
||||||
|
INPUTOUTPUT
|
||||||
|
}
|
||||||
|
|
||||||
|
private DatapointGroupDirection datapointGroupDirection;
|
||||||
|
private int pairingId;
|
||||||
|
|
||||||
|
private String functionString = "";
|
||||||
|
private @Nullable FreeAtHomeDatapoint inputDatapoint;
|
||||||
|
private @Nullable FreeAtHomeDatapoint outputDatapoint;
|
||||||
|
|
||||||
|
FreeAtHomeDatapointGroup() {
|
||||||
|
datapointGroupDirection = DatapointGroupDirection.UNDEFINED;
|
||||||
|
inputDatapoint = null;
|
||||||
|
outputDatapoint = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean addDatapointToGroup(DatapointDirection direction, int neededPairingId, String channelId,
|
||||||
|
JsonObject jsonObjectOfChannel) {
|
||||||
|
FreeAtHomeDatapoint newDatapoint = new FreeAtHomeDatapoint();
|
||||||
|
|
||||||
|
DatapointDirection resultingDirection = newDatapoint.searchForDatapoint(direction, neededPairingId, channelId,
|
||||||
|
jsonObjectOfChannel);
|
||||||
|
|
||||||
|
if (resultingDirection != DatapointDirection.UNKNOWN) {
|
||||||
|
switch (resultingDirection) {
|
||||||
|
case INPUT: {
|
||||||
|
inputDatapoint = newDatapoint;
|
||||||
|
|
||||||
|
pairingId = neededPairingId;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case OUTPUT: {
|
||||||
|
outputDatapoint = newDatapoint;
|
||||||
|
|
||||||
|
if (inputDatapoint == null) {
|
||||||
|
pairingId = neededPairingId;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case INPUTOUTPUT:
|
||||||
|
case INPUT_AS_OUTPUT:
|
||||||
|
case UNKNOWN:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inputDatapoint != null && outputDatapoint != null) {
|
||||||
|
datapointGroupDirection = DatapointGroupDirection.INPUTOUTPUT;
|
||||||
|
} else {
|
||||||
|
if (inputDatapoint == null && outputDatapoint != null) {
|
||||||
|
datapointGroupDirection = DatapointGroupDirection.OUTPUT;
|
||||||
|
} else {
|
||||||
|
if (inputDatapoint != null && outputDatapoint == null) {
|
||||||
|
datapointGroupDirection = DatapointGroupDirection.INPUT;
|
||||||
|
} else {
|
||||||
|
datapointGroupDirection = DatapointGroupDirection.UNDEFINED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return resultingDirection != DatapointDirection.UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void applyChangesForVirtualDevice() {
|
||||||
|
// The input and output datapoints are meant from the device point of view. Because the virtual devices are
|
||||||
|
// outside of the free@home system the input and output datapoint must be switched
|
||||||
|
@Nullable
|
||||||
|
FreeAtHomeDatapoint localDatapoint = inputDatapoint;
|
||||||
|
|
||||||
|
inputDatapoint = outputDatapoint;
|
||||||
|
outputDatapoint = localDatapoint;
|
||||||
|
|
||||||
|
if (inputDatapoint != null && outputDatapoint != null) {
|
||||||
|
datapointGroupDirection = DatapointGroupDirection.INPUTOUTPUT;
|
||||||
|
} else {
|
||||||
|
if (inputDatapoint == null && outputDatapoint != null) {
|
||||||
|
datapointGroupDirection = DatapointGroupDirection.OUTPUT;
|
||||||
|
} else {
|
||||||
|
if (inputDatapoint != null && outputDatapoint == null) {
|
||||||
|
datapointGroupDirection = DatapointGroupDirection.INPUT;
|
||||||
|
} else {
|
||||||
|
datapointGroupDirection = DatapointGroupDirection.UNDEFINED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable FreeAtHomeDatapoint getInputDatapoint() {
|
||||||
|
return inputDatapoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable FreeAtHomeDatapoint getOutputDatapoint() {
|
||||||
|
return outputDatapoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DatapointGroupDirection getDirection() {
|
||||||
|
return datapointGroupDirection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDecimal() throws FreeAtHomeGeneralException {
|
||||||
|
return PidTranslationUtils.PID_VALUETYPE_DECIMAL
|
||||||
|
.equals(PidTranslationUtils.getValueTypeForPairingId(String.format("0x%04X", pairingId)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isInteger() throws FreeAtHomeGeneralException {
|
||||||
|
return PidTranslationUtils.PID_VALUETYPE_INTEGER
|
||||||
|
.equals(PidTranslationUtils.getValueTypeForPairingId(String.format("0x%04X", pairingId)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isReadOnly() {
|
||||||
|
return (DatapointGroupDirection.INPUTOUTPUT == datapointGroupDirection) ? false
|
||||||
|
: ((DatapointGroupDirection.INPUT == datapointGroupDirection) ? false : true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMax() throws FreeAtHomeGeneralException {
|
||||||
|
return PidTranslationUtils.getMax(String.format("0x%04X", pairingId));
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMin() throws FreeAtHomeGeneralException {
|
||||||
|
return PidTranslationUtils.getMin(String.format("0x%04X", pairingId));
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLabel() throws FreeAtHomeGeneralException {
|
||||||
|
return PidTranslationUtils.getShortTextForPairingId(String.format("0x%04X", pairingId));
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() throws FreeAtHomeGeneralException {
|
||||||
|
return PidTranslationUtils.getDescriptionTextForPairingId(String.format("0x%04X", pairingId));
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getValueType() throws FreeAtHomeGeneralException {
|
||||||
|
return PidTranslationUtils.getValueTypeForPairingId(String.format("0x%04X", pairingId));
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTypePattern() throws FreeAtHomeGeneralException {
|
||||||
|
String pattern = "";
|
||||||
|
|
||||||
|
functionString = PidTranslationUtils.getValueTypeForPairingId(String.format("0x%04X", pairingId));
|
||||||
|
|
||||||
|
switch (functionString) {
|
||||||
|
case PidTranslationUtils.PID_VALUETYPE_DECIMAL:
|
||||||
|
pattern = "%.1f";
|
||||||
|
break;
|
||||||
|
case PidTranslationUtils.PID_VALUETYPE_INTEGER:
|
||||||
|
pattern = "%d";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
pattern = "";
|
||||||
|
logger.debug("Type pattern not found for PairingID {} - using default",
|
||||||
|
String.format("0x%04X", pairingId));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ValueStateConverter getValueStateConverter() throws FreeAtHomeGeneralException {
|
||||||
|
ValueStateConverter valueStateConverter = new BooleanValueStateConverter();
|
||||||
|
|
||||||
|
functionString = PidTranslationUtils.getValueTypeForPairingId(String.format("0x%04X", pairingId));
|
||||||
|
|
||||||
|
switch (functionString) {
|
||||||
|
case PidTranslationUtils.PID_VALUETYPE_BOOLEAN:
|
||||||
|
valueStateConverter = new BooleanValueStateConverter();
|
||||||
|
break;
|
||||||
|
case PidTranslationUtils.PID_VALUETYPE_DECIMAL:
|
||||||
|
case PidTranslationUtils.PID_VALUETYPE_INTEGER:
|
||||||
|
valueStateConverter = new DecimalValueStateConverter();
|
||||||
|
break;
|
||||||
|
case PidTranslationUtils.PID_VALUETYPE_STRING:
|
||||||
|
break;
|
||||||
|
case PidTranslationUtils.PID_VALUETYPE_SHUTTERMOVEMENT:
|
||||||
|
valueStateConverter = new ShuttercontrolValueStateConverter();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
valueStateConverter = new DecimalValueStateConverter();
|
||||||
|
logger.debug("Value converter not found for PairingID {} - using default",
|
||||||
|
String.format("0x%04X", pairingId));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return valueStateConverter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOpenHabItemType() throws FreeAtHomeGeneralException {
|
||||||
|
String itemTypeString = "";
|
||||||
|
|
||||||
|
functionString = PidTranslationUtils.getValueTypeForPairingId(String.format("0x%04X", pairingId));
|
||||||
|
|
||||||
|
switch (functionString) {
|
||||||
|
case PidTranslationUtils.PID_VALUETYPE_BOOLEAN:
|
||||||
|
itemTypeString = CoreItemFactory.SWITCH;
|
||||||
|
break;
|
||||||
|
case PidTranslationUtils.PID_VALUETYPE_DECIMAL:
|
||||||
|
case PidTranslationUtils.PID_VALUETYPE_INTEGER:
|
||||||
|
itemTypeString = CoreItemFactory.NUMBER;
|
||||||
|
break;
|
||||||
|
case PidTranslationUtils.PID_VALUETYPE_SHUTTERMOVEMENT:
|
||||||
|
itemTypeString = CoreItemFactory.ROLLERSHUTTER;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
itemTypeString = CoreItemFactory.NUMBER;
|
||||||
|
logger.debug("Item type constant not found for PairingID {} - using default",
|
||||||
|
String.format("0x%04X", pairingId));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return itemTypeString;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOpenHabCategory() throws FreeAtHomeGeneralException {
|
||||||
|
return PidTranslationUtils.getCategoryForPairingId(String.format("0x%04X", pairingId));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,543 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2024 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.freeathomesystem.internal.datamodel;
|
||||||
|
|
||||||
|
import static org.openhab.binding.freeathomesystem.internal.datamodel.FreeAtHomeDatapoint.*;
|
||||||
|
import static org.openhab.binding.freeathomesystem.internal.util.FidTranslationUtils.*;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
import org.openhab.binding.freeathomesystem.internal.util.FidTranslationUtils;
|
||||||
|
import org.openhab.binding.freeathomesystem.internal.util.FreeAtHomeGeneralException;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link FreeAtHomeDeviceChannel} holding the information of device channels
|
||||||
|
*
|
||||||
|
* @author Andras Uhrin - Initial contribution
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class FreeAtHomeDeviceChannel {
|
||||||
|
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(FreeAtHomeDeviceChannel.class);
|
||||||
|
|
||||||
|
private String channelLabel = "";
|
||||||
|
private String channelId = "";
|
||||||
|
private String channelFunctionID = "";
|
||||||
|
|
||||||
|
private List<FreeAtHomeDatapointGroup> datapointGroups = new ArrayList<>();
|
||||||
|
|
||||||
|
public boolean createChannelFromJson(String deviceLabel, String channelId, JsonObject jsonObjectOfChannels,
|
||||||
|
boolean isScene, boolean isRule) {
|
||||||
|
JsonObject channelObject = jsonObjectOfChannels.getAsJsonObject(channelId);
|
||||||
|
|
||||||
|
channelFunctionID = channelObject.get("functionID").getAsString();
|
||||||
|
|
||||||
|
// check whether this is a valid channel
|
||||||
|
if (channelFunctionID.isEmpty()) {
|
||||||
|
// invalid channel found
|
||||||
|
logger.info("Invalid channel function ID found - Devicelabel: {} Channel: {}", deviceLabel, channelId);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!channelFunctionID.isEmpty()) {
|
||||||
|
channelLabel = channelObject.get("displayName").getAsString();
|
||||||
|
|
||||||
|
if (channelLabel.isEmpty()) {
|
||||||
|
channelLabel = deviceLabel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isScene) {
|
||||||
|
channelFunctionID = channelFunctionID.substring(0, channelFunctionID.length() - 1) + "0";
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (Integer.parseInt(channelFunctionID, 16)) {
|
||||||
|
case FID_PANEL_SWITCH_SENSOR:
|
||||||
|
case FID_SWITCH_SENSOR: {
|
||||||
|
this.channelId = channelId;
|
||||||
|
|
||||||
|
logger.debug("Switch sensor channel found - Channel FID: {}", channelFunctionID);
|
||||||
|
|
||||||
|
FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1, channelId, channelObject);
|
||||||
|
|
||||||
|
datapointGroups.add(newDatapointGroup);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FID_PANEL_DIMMING_SENSOR:
|
||||||
|
case FID_DIMMING_SENSOR: {
|
||||||
|
this.channelId = channelId;
|
||||||
|
|
||||||
|
logger.debug("Dimming sensor channel found - Channel FID: {}", channelFunctionID);
|
||||||
|
|
||||||
|
FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 17, channelId, channelObject);
|
||||||
|
|
||||||
|
datapointGroups.add(newDatapointGroup);
|
||||||
|
|
||||||
|
newDatapointGroup = new FreeAtHomeDatapointGroup();
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1, channelId, channelObject);
|
||||||
|
|
||||||
|
datapointGroups.add(newDatapointGroup);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FID_TRIGGER:
|
||||||
|
case FID_SWITCH_ACTUATOR: {
|
||||||
|
this.channelId = channelId;
|
||||||
|
|
||||||
|
logger.debug("Switch actuator channel created - Channel FID: {}", channelFunctionID);
|
||||||
|
|
||||||
|
FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 256, channelId, channelObject);
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.INPUT, 1, channelId, channelObject);
|
||||||
|
|
||||||
|
datapointGroups.add(newDatapointGroup);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FID_MOVEMENT_DETECTOR_FLEX:
|
||||||
|
case FID_MOVEMENT_DETECTOR: {
|
||||||
|
this.channelId = channelId;
|
||||||
|
|
||||||
|
logger.debug("Movement detector channel found - Channel FID: {}", channelFunctionID);
|
||||||
|
|
||||||
|
FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 6, channelId, channelObject);
|
||||||
|
|
||||||
|
datapointGroups.add(newDatapointGroup);
|
||||||
|
|
||||||
|
newDatapointGroup = new FreeAtHomeDatapointGroup();
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 7, channelId, channelObject);
|
||||||
|
|
||||||
|
datapointGroups.add(newDatapointGroup);
|
||||||
|
|
||||||
|
newDatapointGroup = new FreeAtHomeDatapointGroup();
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1027, channelId, channelObject);
|
||||||
|
|
||||||
|
datapointGroups.add(newDatapointGroup);
|
||||||
|
|
||||||
|
newDatapointGroup = new FreeAtHomeDatapointGroup();
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.INPUT_AS_OUTPUT, 256, channelId,
|
||||||
|
channelObject);
|
||||||
|
|
||||||
|
datapointGroups.add(newDatapointGroup);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FID_ROOM_TEMPERATURE_CONTROLLER_MASTER_WITHOUT_FAN:
|
||||||
|
case FID_RADIATOR_ACTUATOR_MASTER: {
|
||||||
|
this.channelId = channelId;
|
||||||
|
|
||||||
|
if (Integer.parseInt(channelFunctionID, 16) == FID_RADIATOR_ACTUATOR_MASTER) {
|
||||||
|
logger.debug("Radiator actuator channel - Channel FID: {}", channelFunctionID);
|
||||||
|
} else {
|
||||||
|
logger.debug("Room temperature actuator channel - Channel FID: {}", channelFunctionID);
|
||||||
|
}
|
||||||
|
|
||||||
|
FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 304, channelId, channelObject);
|
||||||
|
datapointGroups.add(newDatapointGroup);
|
||||||
|
|
||||||
|
newDatapointGroup = new FreeAtHomeDatapointGroup();
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 333, channelId, channelObject);
|
||||||
|
datapointGroups.add(newDatapointGroup);
|
||||||
|
|
||||||
|
newDatapointGroup = new FreeAtHomeDatapointGroup();
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 331, channelId, channelObject);
|
||||||
|
datapointGroups.add(newDatapointGroup);
|
||||||
|
|
||||||
|
newDatapointGroup = new FreeAtHomeDatapointGroup();
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 54, channelId, channelObject);
|
||||||
|
datapointGroups.add(newDatapointGroup);
|
||||||
|
|
||||||
|
newDatapointGroup = new FreeAtHomeDatapointGroup();
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 51, channelId, channelObject);
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.INPUT, 320, channelId, channelObject);
|
||||||
|
datapointGroups.add(newDatapointGroup);
|
||||||
|
|
||||||
|
newDatapointGroup = new FreeAtHomeDatapointGroup();
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 68, channelId, channelObject);
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.INPUT, 58, channelId, channelObject);
|
||||||
|
datapointGroups.add(newDatapointGroup);
|
||||||
|
|
||||||
|
newDatapointGroup = new FreeAtHomeDatapointGroup();
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 56, channelId, channelObject);
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.INPUT, 66, channelId, channelObject);
|
||||||
|
datapointGroups.add(newDatapointGroup);
|
||||||
|
|
||||||
|
// Additional channel for RTC device
|
||||||
|
if (Integer.parseInt(channelFunctionID, 16) == FID_ROOM_TEMPERATURE_CONTROLLER_MASTER_WITHOUT_FAN) {
|
||||||
|
newDatapointGroup = new FreeAtHomeDatapointGroup();
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 48, channelId, channelObject);
|
||||||
|
datapointGroups.add(newDatapointGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FID_WINDOW_DOOR_POSITION_SENSOR:
|
||||||
|
case FID_WINDOW_DOOR_SENSOR: {
|
||||||
|
this.channelId = channelId;
|
||||||
|
|
||||||
|
logger.debug("Window/Door position sensor channel created - Channel FID: {}", channelFunctionID);
|
||||||
|
|
||||||
|
FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 53, channelId, channelObject);
|
||||||
|
datapointGroups.add(newDatapointGroup);
|
||||||
|
|
||||||
|
newDatapointGroup = new FreeAtHomeDatapointGroup();
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 41, channelId, channelObject);
|
||||||
|
datapointGroups.add(newDatapointGroup);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FID_SCENE_TRIGGER: {
|
||||||
|
this.channelId = channelId;
|
||||||
|
|
||||||
|
logger.debug("Scene trigger channel - Channel FID: {}", channelFunctionID);
|
||||||
|
|
||||||
|
FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 4, channelId, channelObject);
|
||||||
|
|
||||||
|
datapointGroups.add(newDatapointGroup);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FID_RULE_SWITCH: {
|
||||||
|
this.channelId = channelId;
|
||||||
|
|
||||||
|
logger.debug("Rule channel - Channel FID: {}", channelFunctionID);
|
||||||
|
|
||||||
|
FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 61698, channelId, channelObject);
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.INPUT, 61697, channelId, channelObject);
|
||||||
|
|
||||||
|
datapointGroups.add(newDatapointGroup);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FID_DES_DOOR_OPENER_ACTUATOR: {
|
||||||
|
this.channelId = channelId;
|
||||||
|
|
||||||
|
logger.debug("Door opener actuator channel - Channel FID: {}", channelFunctionID);
|
||||||
|
|
||||||
|
FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 256, channelId, channelObject);
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.INPUT, 2, channelId, channelObject);
|
||||||
|
|
||||||
|
datapointGroups.add(newDatapointGroup);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FID_DES_LEVEL_CALL_SENSOR:
|
||||||
|
case FID_DES_DOOR_RINGING_SENSOR: {
|
||||||
|
this.channelId = channelId;
|
||||||
|
|
||||||
|
logger.debug("Door ring sensor channel - Channel FID: {}", channelFunctionID);
|
||||||
|
|
||||||
|
FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 2, channelId, channelObject);
|
||||||
|
|
||||||
|
datapointGroups.add(newDatapointGroup);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FID_DES_LIGHT_SWITCH_ACTUATOR: {
|
||||||
|
this.channelId = channelId;
|
||||||
|
|
||||||
|
logger.debug("DES light switch channel - Channel FID: {}", channelFunctionID);
|
||||||
|
|
||||||
|
FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 256, channelId, channelObject);
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.INPUT, 2, channelId, channelObject);
|
||||||
|
|
||||||
|
datapointGroups.add(newDatapointGroup);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FID_DIMMING_ACTUATOR_FLEX:
|
||||||
|
case FID_DIMMING_ACTUATOR: {
|
||||||
|
this.channelId = channelId;
|
||||||
|
|
||||||
|
logger.debug("Dimming actuator channel - Channel FID: {}", channelFunctionID);
|
||||||
|
|
||||||
|
FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 272, channelId, channelObject);
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.INPUT, 17, channelId, channelObject);
|
||||||
|
|
||||||
|
datapointGroups.add(newDatapointGroup);
|
||||||
|
|
||||||
|
newDatapointGroup = new FreeAtHomeDatapointGroup();
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 256, channelId, channelObject);
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.INPUT, 1, channelId, channelObject);
|
||||||
|
|
||||||
|
datapointGroups.add(newDatapointGroup);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FID_AWNING_ACTUATOR:
|
||||||
|
case FID_ATTIC_WINDOW_ACTUATOR:
|
||||||
|
case FID_BLIND_ACTUATOR:
|
||||||
|
case FID_SHUTTER_ACTUATOR: {
|
||||||
|
this.channelId = channelId;
|
||||||
|
|
||||||
|
logger.debug("Shutter actuator channel - Channel FID: {}", channelFunctionID);
|
||||||
|
|
||||||
|
FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.INPUT, 32, channelId, channelObject);
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 288, channelId, channelObject);
|
||||||
|
datapointGroups.add(newDatapointGroup);
|
||||||
|
|
||||||
|
newDatapointGroup = new FreeAtHomeDatapointGroup();
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.INPUT, 33, channelId, channelObject);
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 288, channelId, channelObject);
|
||||||
|
datapointGroups.add(newDatapointGroup);
|
||||||
|
|
||||||
|
newDatapointGroup = new FreeAtHomeDatapointGroup();
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 289, channelId, channelObject);
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.INPUT, 35, channelId, channelObject);
|
||||||
|
|
||||||
|
datapointGroups.add(newDatapointGroup);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FID_BRIGHTNESS_SENSOR: {
|
||||||
|
this.channelId = channelId;
|
||||||
|
|
||||||
|
logger.debug("Brightness sensor channel - Channel FID: {}", channelFunctionID);
|
||||||
|
|
||||||
|
FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1026, channelId, channelObject);
|
||||||
|
datapointGroups.add(newDatapointGroup);
|
||||||
|
|
||||||
|
newDatapointGroup = new FreeAtHomeDatapointGroup();
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1027, channelId, channelObject);
|
||||||
|
datapointGroups.add(newDatapointGroup);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FID_RAIN_SENSOR: {
|
||||||
|
this.channelId = channelId;
|
||||||
|
|
||||||
|
logger.debug("Rain sensor channel - Channel FID: {}", channelFunctionID);
|
||||||
|
|
||||||
|
FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 39, channelId, channelObject);
|
||||||
|
datapointGroups.add(newDatapointGroup);
|
||||||
|
|
||||||
|
newDatapointGroup = new FreeAtHomeDatapointGroup();
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1029, channelId, channelObject);
|
||||||
|
datapointGroups.add(newDatapointGroup);
|
||||||
|
|
||||||
|
newDatapointGroup = new FreeAtHomeDatapointGroup();
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1030, channelId, channelObject);
|
||||||
|
datapointGroups.add(newDatapointGroup);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FID_TEMPERATURE_SENSOR: {
|
||||||
|
this.channelId = channelId;
|
||||||
|
|
||||||
|
logger.debug("Temperature sensor channel - Channel FID: {}", channelFunctionID);
|
||||||
|
|
||||||
|
FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
|
||||||
|
if (newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 38, channelId, channelObject)) {
|
||||||
|
datapointGroups.add(newDatapointGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
newDatapointGroup = new FreeAtHomeDatapointGroup();
|
||||||
|
if (newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1024, channelId, channelObject)) {
|
||||||
|
datapointGroups.add(newDatapointGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
newDatapointGroup = new FreeAtHomeDatapointGroup();
|
||||||
|
if (newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 304, channelId, channelObject)) {
|
||||||
|
datapointGroups.add(newDatapointGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FID_WIND_SENSOR: {
|
||||||
|
this.channelId = channelId;
|
||||||
|
|
||||||
|
logger.debug("Wind sensor channel - Channel FID: {}", channelFunctionID);
|
||||||
|
|
||||||
|
FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 37, channelId, channelObject);
|
||||||
|
datapointGroups.add(newDatapointGroup);
|
||||||
|
|
||||||
|
newDatapointGroup = new FreeAtHomeDatapointGroup();
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1025, channelId, channelObject);
|
||||||
|
datapointGroups.add(newDatapointGroup);
|
||||||
|
|
||||||
|
newDatapointGroup = new FreeAtHomeDatapointGroup();
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1028, channelId, channelObject);
|
||||||
|
datapointGroups.add(newDatapointGroup);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FID_AIRQUALITYSENSOR_CO: {
|
||||||
|
this.channelId = channelId;
|
||||||
|
|
||||||
|
logger.debug("AQS CO channel - Channel FID: {}", channelFunctionID);
|
||||||
|
|
||||||
|
FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1564, channelId, channelObject);
|
||||||
|
datapointGroups.add(newDatapointGroup);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FID_AIRQUALITYSENSOR_CO2: {
|
||||||
|
this.channelId = channelId;
|
||||||
|
|
||||||
|
logger.debug("AQS CO2 channel - Channel FID: {}", channelFunctionID);
|
||||||
|
|
||||||
|
FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1563, channelId, channelObject);
|
||||||
|
datapointGroups.add(newDatapointGroup);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FID_AIRQUALITYSENSOR_HUMIDITY: {
|
||||||
|
this.channelId = channelId;
|
||||||
|
|
||||||
|
logger.debug("AQS Humidity channel - Channel FID: {}", channelFunctionID);
|
||||||
|
|
||||||
|
FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 337, channelId, channelObject);
|
||||||
|
datapointGroups.add(newDatapointGroup);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FID_AIRQUALITYSENSOR_PRESSURE: {
|
||||||
|
this.channelId = channelId;
|
||||||
|
|
||||||
|
logger.debug("AQS Pressure channel - Channel FID: {}", channelFunctionID);
|
||||||
|
|
||||||
|
FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1562, channelId, channelObject);
|
||||||
|
datapointGroups.add(newDatapointGroup);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FID_AIRQUALITYSENSOR_NO2: {
|
||||||
|
this.channelId = channelId;
|
||||||
|
|
||||||
|
logger.debug("AQS NO2 channel - Channel FID: {}", channelFunctionID);
|
||||||
|
|
||||||
|
FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1565, channelId, channelObject);
|
||||||
|
datapointGroups.add(newDatapointGroup);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FID_AIRQUALITYSENSOR_O3: {
|
||||||
|
this.channelId = channelId;
|
||||||
|
|
||||||
|
logger.debug("AQS O3 channel - Channel FID: {}", channelFunctionID);
|
||||||
|
|
||||||
|
FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1566, channelId, channelObject);
|
||||||
|
datapointGroups.add(newDatapointGroup);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FID_AIRQUALITYSENSOR_PM10: {
|
||||||
|
this.channelId = channelId;
|
||||||
|
|
||||||
|
logger.debug("AQS PM10 channel - Channel FID: {}", channelFunctionID);
|
||||||
|
|
||||||
|
FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1567, channelId, channelObject);
|
||||||
|
datapointGroups.add(newDatapointGroup);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FID_AIRQUALITYSENSOR_VOC: {
|
||||||
|
this.channelId = channelId;
|
||||||
|
|
||||||
|
logger.debug("AQS VOC channel - Channel FID: {}", channelFunctionID);
|
||||||
|
|
||||||
|
FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1569, channelId, channelObject);
|
||||||
|
datapointGroups.add(newDatapointGroup);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FID_AIRQUALITYSENSOR_PM25: {
|
||||||
|
this.channelId = channelId;
|
||||||
|
|
||||||
|
logger.debug("AQS PM25 channel - Channel FID: {}", channelFunctionID);
|
||||||
|
|
||||||
|
FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
|
||||||
|
newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1568, channelId, channelObject);
|
||||||
|
datapointGroups.add(newDatapointGroup);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
logger.debug("Unknown channel found - Channel FID: {}", channelFunctionID);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getChannelIdforDatapoint() {
|
||||||
|
return channelId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getChannelLabel() {
|
||||||
|
return channelLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getChannelId() {
|
||||||
|
return channelId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFunctionId() {
|
||||||
|
return channelFunctionID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable String getFunctionIdText() throws FreeAtHomeGeneralException {
|
||||||
|
String functionIdText = FidTranslationUtils
|
||||||
|
.getFunctionIdText(String.format("0x%04X", Integer.parseInt(channelFunctionID, 16)));
|
||||||
|
return functionIdText;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNumberOfDatapointGroup() {
|
||||||
|
return datapointGroups.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public FreeAtHomeDatapointGroup getDatapointGroup(int idx) {
|
||||||
|
return datapointGroups.get(idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void applyChangesForVirtualDevice() {
|
||||||
|
for (FreeAtHomeDatapointGroup localDatapointGroup : datapointGroups) {
|
||||||
|
localDatapointGroup.applyChangesForVirtualDevice();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,154 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2024 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.freeathomesystem.internal.datamodel;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link FreeAtHomeDeviceDescription} is responsible for determining the device type
|
||||||
|
* based on the received json string
|
||||||
|
*
|
||||||
|
* @author Andras Uhrin - Initial contribution
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class FreeAtHomeDeviceDescription {
|
||||||
|
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(FreeAtHomeDeviceDescription.class);
|
||||||
|
|
||||||
|
// interface strings
|
||||||
|
public static final String DEVICE_INTERFACE_UNKNOWN_TYPE = "unknown";
|
||||||
|
public static final String DEVICE_INTERFACE_WIRELESS_TYPE = "wireless";
|
||||||
|
public static final String DEVICE_INTERFACE_VIRTUAL_TYPE = "virtual";
|
||||||
|
public static final String DEVICE_INTERFACE_WIRED_TYPE = "wired";
|
||||||
|
public static final String DEVICE_INTERFACE_HUE_TYPE = "hue";
|
||||||
|
|
||||||
|
public String deviceLabel = "";
|
||||||
|
public String deviceId = "";
|
||||||
|
public String interfaceType = "";
|
||||||
|
public boolean validDevice = false;
|
||||||
|
|
||||||
|
private boolean sceneIsDetected;
|
||||||
|
private boolean ruleIsDetected;
|
||||||
|
|
||||||
|
public List<FreeAtHomeDeviceChannel> listOfChannels = new ArrayList<>();
|
||||||
|
|
||||||
|
public FreeAtHomeDeviceDescription() {
|
||||||
|
validDevice = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FreeAtHomeDeviceDescription(JsonObject jsonObject, String id) {
|
||||||
|
// set the device ID
|
||||||
|
deviceId = id;
|
||||||
|
|
||||||
|
// set the device invalid at first
|
||||||
|
validDevice = false;
|
||||||
|
|
||||||
|
sceneIsDetected = id.toLowerCase().startsWith("ffff48");
|
||||||
|
ruleIsDetected = id.toLowerCase().startsWith("ffff4a");
|
||||||
|
|
||||||
|
JsonObject jsonObjectOfId = jsonObject.getAsJsonObject(id);
|
||||||
|
|
||||||
|
if (jsonObjectOfId == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonElement jsonObjectOfInterface = jsonObjectOfId.get("interface");
|
||||||
|
|
||||||
|
if (jsonObjectOfInterface != null) {
|
||||||
|
String interfaceString = jsonObjectOfInterface.getAsString();
|
||||||
|
|
||||||
|
if (interfaceString.toLowerCase().startsWith("vdev:")) {
|
||||||
|
interfaceType = DEVICE_INTERFACE_VIRTUAL_TYPE;
|
||||||
|
} else if (interfaceString.toLowerCase().startsWith("hue")) {
|
||||||
|
interfaceType = DEVICE_INTERFACE_HUE_TYPE;
|
||||||
|
} else if (interfaceString.toLowerCase().startsWith("rf")) {
|
||||||
|
interfaceType = DEVICE_INTERFACE_WIRELESS_TYPE;
|
||||||
|
} else if (interfaceString.toLowerCase().startsWith("tp")) {
|
||||||
|
interfaceType = DEVICE_INTERFACE_WIRED_TYPE;
|
||||||
|
} else {
|
||||||
|
interfaceType = DEVICE_INTERFACE_UNKNOWN_TYPE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
interfaceType = DEVICE_INTERFACE_UNKNOWN_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonElement jsonObjectOfDeviceLabel = jsonObjectOfId.get("displayName");
|
||||||
|
|
||||||
|
if (jsonObjectOfDeviceLabel == null) {
|
||||||
|
this.deviceLabel = "NoName";
|
||||||
|
} else {
|
||||||
|
this.deviceLabel = jsonObjectOfDeviceLabel.getAsString();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.deviceLabel.isEmpty()) {
|
||||||
|
this.deviceLabel = "NoName";
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonObject jsonObjectOfChannels = jsonObjectOfId.getAsJsonObject("channels");
|
||||||
|
|
||||||
|
logger.debug("Detecting device features - device id: {} - device label: {}", this.deviceId, this.deviceLabel);
|
||||||
|
|
||||||
|
if (jsonObjectOfChannels != null) {
|
||||||
|
// Scan channels for functions
|
||||||
|
for (String nextChannel : jsonObjectOfChannels.keySet()) {
|
||||||
|
FreeAtHomeDeviceChannel newChannel = new FreeAtHomeDeviceChannel();
|
||||||
|
|
||||||
|
if (newChannel.createChannelFromJson(deviceLabel, nextChannel, jsonObjectOfChannels, sceneIsDetected,
|
||||||
|
ruleIsDetected)) {
|
||||||
|
if (interfaceType == DEVICE_INTERFACE_VIRTUAL_TYPE) {
|
||||||
|
newChannel.applyChangesForVirtualDevice();
|
||||||
|
}
|
||||||
|
|
||||||
|
listOfChannels.add(newChannel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRule() {
|
||||||
|
return ruleIsDetected;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isScene() {
|
||||||
|
return sceneIsDetected;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isVirtual() {
|
||||||
|
return interfaceType == DEVICE_INTERFACE_VIRTUAL_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNumberOfChannels() {
|
||||||
|
return listOfChannels.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public FreeAtHomeDeviceChannel getChannel(int idx) {
|
||||||
|
return listOfChannels.get(idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDeviceId() {
|
||||||
|
return deviceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDeviceLabel() {
|
||||||
|
return deviceLabel;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,897 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2024 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.freeathomesystem.internal.handler;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.StringReader;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Base64;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.concurrent.locks.Condition;
|
||||||
|
import java.util.concurrent.locks.Lock;
|
||||||
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
import org.eclipse.jetty.client.HttpClient;
|
||||||
|
import org.eclipse.jetty.client.api.AuthenticationStore;
|
||||||
|
import org.eclipse.jetty.client.api.ContentResponse;
|
||||||
|
import org.eclipse.jetty.client.api.Request;
|
||||||
|
import org.eclipse.jetty.client.util.BasicAuthentication;
|
||||||
|
import org.eclipse.jetty.client.util.StringContentProvider;
|
||||||
|
import org.eclipse.jetty.http.HttpMethod;
|
||||||
|
import org.eclipse.jetty.http.HttpStatus;
|
||||||
|
import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
||||||
|
import org.eclipse.jetty.websocket.api.Session;
|
||||||
|
import org.eclipse.jetty.websocket.api.StatusCode;
|
||||||
|
import org.eclipse.jetty.websocket.api.WebSocketListener;
|
||||||
|
import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
|
||||||
|
import org.eclipse.jetty.websocket.client.WebSocketClient;
|
||||||
|
import org.openhab.binding.freeathomesystem.internal.FreeAtHomeSystemDiscoveryService;
|
||||||
|
import org.openhab.binding.freeathomesystem.internal.configuration.FreeAtHomeBridgeHandlerConfiguration;
|
||||||
|
import org.openhab.binding.freeathomesystem.internal.datamodel.FreeAtHomeDeviceDescription;
|
||||||
|
import org.openhab.binding.freeathomesystem.internal.util.FreeAtHomeHttpCommunicationException;
|
||||||
|
import org.openhab.core.thing.Bridge;
|
||||||
|
import org.openhab.core.thing.ChannelUID;
|
||||||
|
import org.openhab.core.thing.ThingStatus;
|
||||||
|
import org.openhab.core.thing.ThingStatusDetail;
|
||||||
|
import org.openhab.core.thing.binding.BaseBridgeHandler;
|
||||||
|
import org.openhab.core.thing.binding.ThingHandlerService;
|
||||||
|
import org.openhab.core.types.Command;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.google.gson.JsonParseException;
|
||||||
|
import com.google.gson.JsonParser;
|
||||||
|
import com.google.gson.stream.JsonReader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link FreeAtHomeBridgeHandler} is responsible for handling the free@home bridge and
|
||||||
|
* its main communication.
|
||||||
|
*
|
||||||
|
* @author Andras Uhrin - Initial contribution
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class FreeAtHomeBridgeHandler extends BaseBridgeHandler implements WebSocketListener {
|
||||||
|
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(FreeAtHomeBridgeHandler.class);
|
||||||
|
|
||||||
|
private Map<String, FreeAtHomeDeviceHandler> mapEventListeners = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
// Clients for the network communication
|
||||||
|
private HttpClient httpClient;
|
||||||
|
private @Nullable WebSocketClient websocketClient = null;
|
||||||
|
private FreeAtHomeWebsocketMonitorThread socketMonitor = new FreeAtHomeWebsocketMonitorThread();
|
||||||
|
private @Nullable QueuedThreadPool jettyThreadPool = null;
|
||||||
|
private volatile @Nullable Session websocketSession = null;
|
||||||
|
|
||||||
|
private String sysApUID = "00000000-0000-0000-0000-000000000000";
|
||||||
|
private String ipAddress = "";
|
||||||
|
private String username = "";
|
||||||
|
private String password = "";
|
||||||
|
|
||||||
|
private String baseUrl = "";
|
||||||
|
|
||||||
|
private String authField = "";
|
||||||
|
|
||||||
|
private Lock lock = new ReentrantLock();
|
||||||
|
private AtomicBoolean httpConnectionOK = new AtomicBoolean(false);
|
||||||
|
private Condition websocketSessionEstablished = lock.newCondition();
|
||||||
|
|
||||||
|
int numberOfComponents = 0;
|
||||||
|
|
||||||
|
private static final int BRIDGE_WEBSOCKET_RECONNECT_DELAY = 60;
|
||||||
|
private static final int BRIDGE_WEBSOCKET_TIMEOUT = 90;
|
||||||
|
private static final int BRIDGE_WEBSOCKET_KEEPALIVE = 50;
|
||||||
|
private static final String BRIDGE_URL_GETDEVICELIST = "/rest/devicelist";
|
||||||
|
|
||||||
|
public FreeAtHomeBridgeHandler(Bridge thing, HttpClient client) {
|
||||||
|
super(thing);
|
||||||
|
|
||||||
|
httpClient = client;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* stub method for handlCommand
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||||
|
logger.warn("Unknown handle command for the bridge - channellUID {}, command {}", channelUID, command);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<Class<? extends ThingHandlerService>> getServices() {
|
||||||
|
return List.of(FreeAtHomeSystemDiscoveryService.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to get the device list
|
||||||
|
*/
|
||||||
|
public List<String> getDeviceDeviceList() throws FreeAtHomeHttpCommunicationException {
|
||||||
|
List<String> listOfComponentId = new ArrayList<String>();
|
||||||
|
boolean ret = false;
|
||||||
|
|
||||||
|
listOfComponentId.clear();
|
||||||
|
|
||||||
|
String url = baseUrl + BRIDGE_URL_GETDEVICELIST;
|
||||||
|
|
||||||
|
// Perform a simple GET and wait for the response.
|
||||||
|
try {
|
||||||
|
HttpClient client = httpClient;
|
||||||
|
|
||||||
|
Request req = client.newRequest(url);
|
||||||
|
|
||||||
|
if (req == null) {
|
||||||
|
throw new FreeAtHomeHttpCommunicationException(0,
|
||||||
|
"Invalid request object in getDeviceDeviceList with the URL [ " + url + " ]");
|
||||||
|
}
|
||||||
|
|
||||||
|
ContentResponse response = req.send();
|
||||||
|
|
||||||
|
// Get component List
|
||||||
|
String componentListString = new String(response.getContent());
|
||||||
|
|
||||||
|
JsonElement jsonTree = JsonParser.parseString(componentListString);
|
||||||
|
|
||||||
|
// check the output
|
||||||
|
if (!jsonTree.isJsonObject()) {
|
||||||
|
throw new FreeAtHomeHttpCommunicationException(0,
|
||||||
|
"Invalid jsonObject in getDeviceDeviceList with the URL [ " + url + " ]");
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonObject jsonObject = jsonTree.getAsJsonObject();
|
||||||
|
|
||||||
|
// Get the main object
|
||||||
|
JsonElement listOfComponents = jsonObject.get(sysApUID);
|
||||||
|
|
||||||
|
if (listOfComponents == null) {
|
||||||
|
throw new FreeAtHomeHttpCommunicationException(0,
|
||||||
|
"Devices Section is missing in getDeviceDeviceList with the URL [ " + url + " ]");
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonArray array = listOfComponents.getAsJsonArray();
|
||||||
|
|
||||||
|
this.numberOfComponents = array.size();
|
||||||
|
|
||||||
|
for (int i = 0; i < array.size(); i++) {
|
||||||
|
JsonElement basicElement = array.get(i);
|
||||||
|
|
||||||
|
listOfComponentId.add(basicElement.getAsString());
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = true;
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
logger.debug("Error to build up the Component list [ {} ]", e.getMessage());
|
||||||
|
|
||||||
|
throw new FreeAtHomeHttpCommunicationException(0,
|
||||||
|
"Http communication interrupted [ " + e.getMessage() + " ]");
|
||||||
|
} catch (ExecutionException | TimeoutException e) {
|
||||||
|
logger.debug("Error to build up the Component list [ {} ]", e.getMessage());
|
||||||
|
|
||||||
|
throw new FreeAtHomeHttpCommunicationException(0,
|
||||||
|
"Http communication interrupted in getDeviceList [ " + e.getMessage() + " ]");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scan finished but error. clear the list
|
||||||
|
if (!ret) {
|
||||||
|
listOfComponentId.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
return listOfComponentId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to send http request to get the device description
|
||||||
|
*/
|
||||||
|
public FreeAtHomeDeviceDescription getFreeatHomeDeviceDescription(String id)
|
||||||
|
throws FreeAtHomeHttpCommunicationException {
|
||||||
|
FreeAtHomeDeviceDescription device = new FreeAtHomeDeviceDescription();
|
||||||
|
|
||||||
|
String url = baseUrl + "/rest/device/" + sysApUID + "/" + id;
|
||||||
|
try {
|
||||||
|
HttpClient client = httpClient;
|
||||||
|
Request req = client.newRequest(url);
|
||||||
|
|
||||||
|
if (req == null) {
|
||||||
|
throw new FreeAtHomeHttpCommunicationException(0,
|
||||||
|
"Invalid request object in getDatapoint with the URL [ " + url + " ]");
|
||||||
|
}
|
||||||
|
|
||||||
|
ContentResponse response;
|
||||||
|
response = req.send();
|
||||||
|
|
||||||
|
// Get component List
|
||||||
|
String deviceString = new String(response.getContent());
|
||||||
|
|
||||||
|
JsonReader reader = new JsonReader(new StringReader(deviceString));
|
||||||
|
reader.setLenient(true);
|
||||||
|
JsonElement jsonTree = JsonParser.parseReader(reader);
|
||||||
|
|
||||||
|
if (!jsonTree.isJsonObject()) {
|
||||||
|
throw new FreeAtHomeHttpCommunicationException(0,
|
||||||
|
"No data is received by getDatapoint with the URL [ " + url + " ]");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!jsonTree.isJsonObject()) {
|
||||||
|
throw new FreeAtHomeHttpCommunicationException(0,
|
||||||
|
"Invalid jsonObject in getFreeatHomeDeviceDescription with the URL [ " + url + " ]");
|
||||||
|
}
|
||||||
|
|
||||||
|
// check the output
|
||||||
|
JsonObject jsonObject = jsonTree.getAsJsonObject();
|
||||||
|
|
||||||
|
if (!jsonObject.isJsonObject()) {
|
||||||
|
throw new FreeAtHomeHttpCommunicationException(0,
|
||||||
|
"Main jsonObject is invalid in getFreeatHomeDeviceDescription with the URL [ " + url + " ]");
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonObject = jsonObject.getAsJsonObject(sysApUID);
|
||||||
|
|
||||||
|
if (!jsonObject.isJsonObject()) {
|
||||||
|
throw new FreeAtHomeHttpCommunicationException(0,
|
||||||
|
"jsonObject is invalid in getFreeatHomeDeviceDescription with the URL [ " + url + " ]");
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonObject = jsonObject.getAsJsonObject("devices");
|
||||||
|
|
||||||
|
if (!jsonObject.isJsonObject()) {
|
||||||
|
throw new FreeAtHomeHttpCommunicationException(0,
|
||||||
|
"Devices Section is missing in getFreeatHomeDeviceDescription with the URL [ " + url + " ]");
|
||||||
|
}
|
||||||
|
|
||||||
|
device = new FreeAtHomeDeviceDescription(jsonObject, id);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
logger.debug("No communication possible to get device list - Communication interrupt [ {} ]",
|
||||||
|
e.getMessage());
|
||||||
|
|
||||||
|
throw new FreeAtHomeHttpCommunicationException(0,
|
||||||
|
"Http communication interrupted [ " + e.getMessage() + " ]");
|
||||||
|
} catch (ExecutionException | TimeoutException e) {
|
||||||
|
logger.debug("No communication possible to get device list - Communication interrupt [ {} ]",
|
||||||
|
e.getMessage());
|
||||||
|
|
||||||
|
throw new FreeAtHomeHttpCommunicationException(0,
|
||||||
|
"Http communication interrupted in getDeviceList [ " + e.getMessage() + " ]");
|
||||||
|
}
|
||||||
|
|
||||||
|
return device;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to get datapoint values for devices
|
||||||
|
*/
|
||||||
|
public String getDatapoint(String deviceId, String channel, String datapoint)
|
||||||
|
throws FreeAtHomeHttpCommunicationException {
|
||||||
|
String url = baseUrl + "/rest/datapoint/" + sysApUID + "/" + deviceId + "." + channel + "." + datapoint;
|
||||||
|
|
||||||
|
try {
|
||||||
|
Request req = httpClient.newRequest(url);
|
||||||
|
|
||||||
|
logger.debug("Get datapoint by url: {}", url);
|
||||||
|
|
||||||
|
if (req == null) {
|
||||||
|
throw new FreeAtHomeHttpCommunicationException(0,
|
||||||
|
"Invalid request object in getDatapoint with the URL [ " + url + " ]");
|
||||||
|
}
|
||||||
|
|
||||||
|
ContentResponse response = req.send();
|
||||||
|
|
||||||
|
if (response.getStatus() != 200) {
|
||||||
|
throw new FreeAtHomeHttpCommunicationException(response.getStatus(), response.getReason());
|
||||||
|
}
|
||||||
|
|
||||||
|
String deviceString = new String(response.getContent());
|
||||||
|
|
||||||
|
JsonReader reader = new JsonReader(new StringReader(deviceString));
|
||||||
|
reader.setLenient(true);
|
||||||
|
JsonElement jsonTree = JsonParser.parseReader(reader);
|
||||||
|
|
||||||
|
if (!jsonTree.isJsonObject()) {
|
||||||
|
throw new FreeAtHomeHttpCommunicationException(0,
|
||||||
|
"No data is received by getDatapoint with the URL [ " + url + " ]");
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonObject jsonObject = jsonTree.getAsJsonObject();
|
||||||
|
|
||||||
|
jsonObject = jsonObject.getAsJsonObject(sysApUID);
|
||||||
|
JsonArray jsonValueArray = jsonObject.getAsJsonArray("values");
|
||||||
|
|
||||||
|
JsonElement element = jsonValueArray.get(0);
|
||||||
|
String value = element.getAsString();
|
||||||
|
|
||||||
|
if (value.isEmpty()) {
|
||||||
|
value = "0";
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||||
|
"@text/comm-error.error-in-sysap-com");
|
||||||
|
|
||||||
|
throw new FreeAtHomeHttpCommunicationException(0,
|
||||||
|
"Http communication interrupted [ " + e.getMessage() + " ]");
|
||||||
|
} catch (ExecutionException | TimeoutException e) {
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||||
|
"@text/comm-error.error-in-sysap-com");
|
||||||
|
|
||||||
|
throw new FreeAtHomeHttpCommunicationException(0,
|
||||||
|
"Http communication timout or execution interrupted [ " + e.getMessage() + " ]");
|
||||||
|
} catch (JsonParseException e) {
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||||
|
"@text/comm-error.error-in-sysap-com");
|
||||||
|
|
||||||
|
throw new FreeAtHomeHttpCommunicationException(0,
|
||||||
|
"Invalid JSON file is received by getDatapoint with the URL [ " + e.getMessage() + " ]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to set datapoint values in channels
|
||||||
|
*/
|
||||||
|
public boolean setDatapoint(String deviceId, String channel, String datapoint, String valueString)
|
||||||
|
throws FreeAtHomeHttpCommunicationException {
|
||||||
|
String url = baseUrl + "/rest/datapoint/" + sysApUID + "/" + deviceId + "." + channel + "." + datapoint;
|
||||||
|
|
||||||
|
try {
|
||||||
|
Request req = httpClient.newRequest(url);
|
||||||
|
|
||||||
|
if (req == null) {
|
||||||
|
throw new FreeAtHomeHttpCommunicationException(0,
|
||||||
|
"Invalid request object in getDatapoint with the URL [ " + url + " ]");
|
||||||
|
}
|
||||||
|
|
||||||
|
req.content(new StringContentProvider(valueString));
|
||||||
|
req.method(HttpMethod.PUT);
|
||||||
|
|
||||||
|
logger.debug("Set datapoint by url: {} value: {}", url, valueString);
|
||||||
|
|
||||||
|
ContentResponse response = req.send();
|
||||||
|
|
||||||
|
if (response.getStatus() != 200) {
|
||||||
|
throw new FreeAtHomeHttpCommunicationException(response.getStatus(), response.getReason());
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||||
|
"@text/comm-error.error-in-sysap-com");
|
||||||
|
|
||||||
|
throw new FreeAtHomeHttpCommunicationException(0,
|
||||||
|
"Http communication interrupted [ " + e.getMessage() + " ]");
|
||||||
|
} catch (ExecutionException | TimeoutException e) {
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||||
|
"@text/comm-error.error-in-sysap-com");
|
||||||
|
|
||||||
|
throw new FreeAtHomeHttpCommunicationException(0,
|
||||||
|
"Http communication interrupted [ " + e.getMessage() + " ]");
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to process socket events
|
||||||
|
*/
|
||||||
|
public void setDatapointOnWebsocketFeedback(String receivedText) {
|
||||||
|
JsonReader reader = new JsonReader(new StringReader(receivedText));
|
||||||
|
reader.setLenient(true);
|
||||||
|
JsonElement jsonTree = JsonParser.parseReader(reader);
|
||||||
|
|
||||||
|
// check the output
|
||||||
|
if (jsonTree.isJsonObject()) {
|
||||||
|
JsonObject jsonObject = jsonTree.getAsJsonObject();
|
||||||
|
|
||||||
|
jsonObject = jsonObject.getAsJsonObject(sysApUID);
|
||||||
|
jsonObject = jsonObject.getAsJsonObject("datapoints");
|
||||||
|
|
||||||
|
Set<String> keys = jsonObject.keySet();
|
||||||
|
|
||||||
|
Iterator<String> iter = keys.iterator();
|
||||||
|
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
String eventDatapointID = iter.next();
|
||||||
|
|
||||||
|
JsonElement element = jsonObject.get(eventDatapointID);
|
||||||
|
String value = element.getAsString();
|
||||||
|
|
||||||
|
String[] parts = eventDatapointID.split("/");
|
||||||
|
|
||||||
|
FreeAtHomeDeviceHandler deviceHandler = mapEventListeners.get(parts[0]);
|
||||||
|
|
||||||
|
if (deviceHandler != null) {
|
||||||
|
deviceHandler.onDeviceStateChanged(eventDatapointID, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.debug("Socket event processed: event-datapoint-ID {} value {}", eventDatapointID, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void markDeviceRemovedOnWebsocketFeedback(String receivedText) {
|
||||||
|
JsonReader reader = new JsonReader(new StringReader(receivedText));
|
||||||
|
reader.setLenient(true);
|
||||||
|
JsonElement jsonTree = JsonParser.parseReader(reader);
|
||||||
|
|
||||||
|
// check the output
|
||||||
|
if (jsonTree.isJsonObject()) {
|
||||||
|
JsonObject jsonObject = jsonTree.getAsJsonObject();
|
||||||
|
|
||||||
|
jsonObject = jsonObject.getAsJsonObject(sysApUID);
|
||||||
|
JsonArray jsonArray = jsonObject.getAsJsonArray("devicesRemoved");
|
||||||
|
|
||||||
|
for (JsonElement element : jsonArray) {
|
||||||
|
FreeAtHomeDeviceHandler deviceHandler = mapEventListeners.get(element.getAsString());
|
||||||
|
|
||||||
|
if (deviceHandler != null) {
|
||||||
|
deviceHandler.onDeviceRemoved();
|
||||||
|
|
||||||
|
logger.debug("Device removal processed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void registerDeviceStateListener(String deviceID, FreeAtHomeDeviceHandler deviceHandler) {
|
||||||
|
mapEventListeners.put(deviceID, deviceHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void unregisterDeviceStateListener(String deviceID) {
|
||||||
|
mapEventListeners.remove(deviceID);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to open Http connection
|
||||||
|
*/
|
||||||
|
public boolean openHttpConnection() {
|
||||||
|
boolean ret = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Add authentication credentials.
|
||||||
|
AuthenticationStore auth = httpClient.getAuthenticationStore();
|
||||||
|
|
||||||
|
URI uri1 = new URI(baseUrl);
|
||||||
|
auth.addAuthenticationResult(new BasicAuthentication.BasicResult(uri1, username, password));
|
||||||
|
|
||||||
|
String url = baseUrl + BRIDGE_URL_GETDEVICELIST;
|
||||||
|
|
||||||
|
Request req = httpClient.newRequest(url);
|
||||||
|
ContentResponse res = req.send();
|
||||||
|
|
||||||
|
// check status
|
||||||
|
if (res.getStatus() == HttpStatus.OK_200) {
|
||||||
|
// response OK
|
||||||
|
httpConnectionOK.set(true);
|
||||||
|
|
||||||
|
ret = true;
|
||||||
|
|
||||||
|
logger.debug("HTTP connection to SysAP is OK");
|
||||||
|
} else {
|
||||||
|
// response NOK, set error
|
||||||
|
httpConnectionOK.set(false);
|
||||||
|
|
||||||
|
ret = false;
|
||||||
|
}
|
||||||
|
} catch (URISyntaxException | InterruptedException | ExecutionException | TimeoutException ex) {
|
||||||
|
logger.debug("Initial HTTP connection to SysAP is not successful");
|
||||||
|
|
||||||
|
ret = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to connect the websocket session
|
||||||
|
*/
|
||||||
|
public boolean connectWebsocketSession() {
|
||||||
|
boolean ret = false;
|
||||||
|
|
||||||
|
URI uri = URI.create("ws://" + ipAddress + "/fhapi/v1/api/ws");
|
||||||
|
|
||||||
|
String authString = username + ":" + password;
|
||||||
|
|
||||||
|
// create base64 encoder
|
||||||
|
Base64.Encoder bas64Encoder = Base64.getEncoder();
|
||||||
|
|
||||||
|
// Encoding string using encoder object
|
||||||
|
String authStringEnc = bas64Encoder.encodeToString(authString.getBytes());
|
||||||
|
|
||||||
|
authField = "Basic " + authStringEnc;
|
||||||
|
|
||||||
|
WebSocketClient localWebsocketClient = websocketClient;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Start socket client
|
||||||
|
if (localWebsocketClient != null) {
|
||||||
|
localWebsocketClient.setMaxTextMessageBufferSize(8 * 1024);
|
||||||
|
localWebsocketClient.setMaxIdleTimeout(BRIDGE_WEBSOCKET_TIMEOUT * 60 * 1000);
|
||||||
|
localWebsocketClient.setConnectTimeout(BRIDGE_WEBSOCKET_TIMEOUT * 60 * 1000);
|
||||||
|
localWebsocketClient.start();
|
||||||
|
ClientUpgradeRequest request = new ClientUpgradeRequest();
|
||||||
|
request.setHeader("Authorization", authField);
|
||||||
|
request.setTimeout(BRIDGE_WEBSOCKET_TIMEOUT, TimeUnit.MINUTES);
|
||||||
|
localWebsocketClient.connect(this, uri, request);
|
||||||
|
|
||||||
|
logger.debug("Websocket connection to SysAP is OK, timeout: {}", BRIDGE_WEBSOCKET_TIMEOUT);
|
||||||
|
|
||||||
|
ret = true;
|
||||||
|
} else {
|
||||||
|
ret = false;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.debug("Error by opening Websocket connection [{}]", e.getMessage());
|
||||||
|
|
||||||
|
if (localWebsocketClient != null) {
|
||||||
|
try {
|
||||||
|
localWebsocketClient.stop();
|
||||||
|
|
||||||
|
ret = false;
|
||||||
|
} catch (Exception e1) {
|
||||||
|
logger.debug("Error by opening Websocket connection [{}]", e1.getMessage());
|
||||||
|
|
||||||
|
ret = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ret = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to close the websocket connection
|
||||||
|
*/
|
||||||
|
public void closeWebSocketConnection() {
|
||||||
|
socketMonitor.interrupt();
|
||||||
|
|
||||||
|
QueuedThreadPool localThreadPool = jettyThreadPool;
|
||||||
|
|
||||||
|
if (localThreadPool != null) {
|
||||||
|
try {
|
||||||
|
localThreadPool.stop();
|
||||||
|
} catch (Exception e1) {
|
||||||
|
logger.debug("Error by closing Websocket connection [{}]", e1.getMessage());
|
||||||
|
}
|
||||||
|
jettyThreadPool = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
WebSocketClient localWebSocketClient = websocketClient;
|
||||||
|
|
||||||
|
if (localWebSocketClient != null) {
|
||||||
|
try {
|
||||||
|
localWebSocketClient.stop();
|
||||||
|
} catch (Exception e2) {
|
||||||
|
logger.debug("Error by closing Websocket connection [{}]", e2.getMessage());
|
||||||
|
}
|
||||||
|
websocketClient = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to open the websocket connection
|
||||||
|
*/
|
||||||
|
public boolean openWebSocketConnection() {
|
||||||
|
boolean ret = false;
|
||||||
|
|
||||||
|
QueuedThreadPool localThreadPool = jettyThreadPool;
|
||||||
|
|
||||||
|
if (localThreadPool == null) {
|
||||||
|
jettyThreadPool = new QueuedThreadPool();
|
||||||
|
|
||||||
|
localThreadPool = jettyThreadPool;
|
||||||
|
|
||||||
|
if (localThreadPool != null) {
|
||||||
|
localThreadPool.setName(FreeAtHomeBridgeHandler.class.getSimpleName());
|
||||||
|
localThreadPool.setDaemon(true);
|
||||||
|
localThreadPool.setStopTimeout(0);
|
||||||
|
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WebSocketClient localWebSocketClient = websocketClient;
|
||||||
|
|
||||||
|
if (localWebSocketClient == null) {
|
||||||
|
websocketClient = new WebSocketClient(httpClient);
|
||||||
|
|
||||||
|
localWebSocketClient = websocketClient;
|
||||||
|
|
||||||
|
if (localWebSocketClient != null) {
|
||||||
|
localWebSocketClient.setExecutor(jettyThreadPool);
|
||||||
|
|
||||||
|
socketMonitor.start();
|
||||||
|
|
||||||
|
ret = true;
|
||||||
|
} else {
|
||||||
|
ret = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to initialize the bridge
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void initialize() {
|
||||||
|
httpConnectionOK.set(false);
|
||||||
|
|
||||||
|
// load configuration
|
||||||
|
FreeAtHomeBridgeHandlerConfiguration locConfig = getConfigAs(FreeAtHomeBridgeHandlerConfiguration.class);
|
||||||
|
|
||||||
|
ipAddress = locConfig.ipAddress;
|
||||||
|
if (ipAddress.isBlank()) {
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
|
||||||
|
"@text/conf-error.ip-address-missing");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
password = locConfig.password;
|
||||||
|
if (password.isBlank()) {
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
|
||||||
|
"@text/conf-error.password-missing");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
username = locConfig.username;
|
||||||
|
if (username.isBlank()) {
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
|
||||||
|
"@text/conf-error.username-missing");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// build base URL
|
||||||
|
baseUrl = "http://" + ipAddress + "/fhapi/v1/api";
|
||||||
|
|
||||||
|
updateStatus(ThingStatus.UNKNOWN);
|
||||||
|
|
||||||
|
scheduler.execute(() -> {
|
||||||
|
boolean thingReachable = true;
|
||||||
|
|
||||||
|
// Open Http connection
|
||||||
|
if (!openHttpConnection()) {
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||||
|
"@text/comm-error.http-wrongpass-or-ip");
|
||||||
|
|
||||||
|
thingReachable = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open the websocket connection for immediate status updates
|
||||||
|
if (!openWebSocketConnection()) {
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||||
|
"@text/comm-error.not-able-open-websocketconnection");
|
||||||
|
|
||||||
|
thingReachable = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (thingReachable) {
|
||||||
|
updateStatus(ThingStatus.ONLINE);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to dispose
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void dispose() {
|
||||||
|
// let run out the thread
|
||||||
|
socketMonitor.interrupt();
|
||||||
|
|
||||||
|
closeWebSocketConnection();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thread that maintains connection via Websocket.
|
||||||
|
*/
|
||||||
|
private class FreeAtHomeWebsocketMonitorThread extends Thread {
|
||||||
|
|
||||||
|
// initial delay to initiate connection
|
||||||
|
private AtomicInteger reconnectDelay = new AtomicInteger();
|
||||||
|
|
||||||
|
public FreeAtHomeWebsocketMonitorThread() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
// set initial connect delay to 0
|
||||||
|
reconnectDelay.set(0);
|
||||||
|
|
||||||
|
try {
|
||||||
|
while (!isInterrupted()) {
|
||||||
|
if (httpConnectionOK.get()) {
|
||||||
|
if (connectSession()) {
|
||||||
|
while (isSocketConnectionAlive()) {
|
||||||
|
TimeUnit.SECONDS.sleep(BRIDGE_WEBSOCKET_KEEPALIVE);
|
||||||
|
|
||||||
|
logger.debug("Sending keep-alive message {}", System.currentTimeMillis());
|
||||||
|
sendWebsocketKeepAliveMessage("keep-alive");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
logger.debug("Socket connection closed");
|
||||||
|
reconnectDelay.set(BRIDGE_WEBSOCKET_RECONNECT_DELAY);
|
||||||
|
} else {
|
||||||
|
TimeUnit.SECONDS.sleep(BRIDGE_WEBSOCKET_RECONNECT_DELAY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||||
|
"@text/comm-error.general-websocket-issue");
|
||||||
|
} catch (IOException e) {
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||||
|
"@text/comm-error.websocket-keep-alive-error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean connectSession() throws InterruptedException {
|
||||||
|
int delay = reconnectDelay.get();
|
||||||
|
|
||||||
|
if (delay > 0) {
|
||||||
|
logger.debug("Delaying (re)connect request by {} seconds.", reconnectDelay);
|
||||||
|
TimeUnit.SECONDS.sleep(delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.debug("Server connecting to websocket");
|
||||||
|
|
||||||
|
if (!connectWebsocketSession()) {
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||||
|
"@text/comm-error.general-websocket-issue");
|
||||||
|
|
||||||
|
reconnectDelay.set(BRIDGE_WEBSOCKET_RECONNECT_DELAY);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (websocketSession == null) {
|
||||||
|
lock.lock();
|
||||||
|
try {
|
||||||
|
websocketSessionEstablished.await();
|
||||||
|
} finally {
|
||||||
|
lock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send keep-alive message to SysAp
|
||||||
|
*/
|
||||||
|
public void sendWebsocketKeepAliveMessage(String message) throws IOException {
|
||||||
|
Session localSession = websocketSession;
|
||||||
|
|
||||||
|
if (localSession != null) {
|
||||||
|
localSession.getRemote().sendString(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get socket alive state
|
||||||
|
*
|
||||||
|
* @throws InterruptedException
|
||||||
|
*/
|
||||||
|
public boolean isSocketConnectionAlive() throws InterruptedException {
|
||||||
|
Session localSession = websocketSession;
|
||||||
|
|
||||||
|
return (localSession != null) ? localSession.isOpen() : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Socket closed. Report the state
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onWebSocketClose(int statusCode, @Nullable String reason) {
|
||||||
|
websocketSession = null;
|
||||||
|
logger.debug("Socket Closed: [ {} ] {}", statusCode, reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Socket connected. store the session for later use
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onWebSocketConnect(@Nullable Session session) {
|
||||||
|
Session localSession = session;
|
||||||
|
|
||||||
|
if (localSession != null) {
|
||||||
|
websocketSession = localSession;
|
||||||
|
|
||||||
|
localSession.setIdleTimeout(-1);
|
||||||
|
|
||||||
|
logger.debug("Socket Connected - Timeout {} - sesson: {}", localSession.getIdleTimeout(), session);
|
||||||
|
} else {
|
||||||
|
logger.debug("Socket Connected - Timeout (invalid) - sesson: (invalid)");
|
||||||
|
}
|
||||||
|
|
||||||
|
lock.lock();
|
||||||
|
try {
|
||||||
|
websocketSessionEstablished.signal();
|
||||||
|
} finally {
|
||||||
|
lock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Error caused. Report the state
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onWebSocketError(@Nullable Throwable cause) {
|
||||||
|
websocketSession = null;
|
||||||
|
|
||||||
|
if (cause != null) {
|
||||||
|
logger.debug("Socket Error: {}", cause.getLocalizedMessage());
|
||||||
|
} else {
|
||||||
|
logger.debug("Socket Error: unknown");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Binary message received. It shall not happen with the free@home SysAp
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@NonNullByDefault({})
|
||||||
|
public void onWebSocketBinary(byte[] payload, int offset, int len) {
|
||||||
|
logger.debug("Binary message received via websocket");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Text message received. Processing will be started
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onWebSocketText(@Nullable String message) {
|
||||||
|
if (message != null) {
|
||||||
|
if (message.toLowerCase(Locale.US).contains("bye")) {
|
||||||
|
Session localSession = websocketSession;
|
||||||
|
|
||||||
|
if (localSession != null) {
|
||||||
|
localSession.close(StatusCode.NORMAL, "Thanks");
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.debug("Websocket connection closed: {} ", message);
|
||||||
|
} else {
|
||||||
|
logger.debug("Received websocket text: {} ", message);
|
||||||
|
|
||||||
|
setDatapointOnWebsocketFeedback(message);
|
||||||
|
|
||||||
|
markDeviceRemovedOnWebsocketFeedback(message);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logger.debug("Invalid message string");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,635 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2024 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.freeathomesystem.internal.handler;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.openhab.binding.freeathomesystem.internal.configuration.FreeAtHomeDeviceHandlerConfiguration;
|
||||||
|
import org.openhab.binding.freeathomesystem.internal.datamodel.FreeAtHomeDatapoint;
|
||||||
|
import org.openhab.binding.freeathomesystem.internal.datamodel.FreeAtHomeDatapointGroup;
|
||||||
|
import org.openhab.binding.freeathomesystem.internal.datamodel.FreeAtHomeDeviceChannel;
|
||||||
|
import org.openhab.binding.freeathomesystem.internal.datamodel.FreeAtHomeDeviceDescription;
|
||||||
|
import org.openhab.binding.freeathomesystem.internal.type.FreeAtHomeChannelTypeProvider;
|
||||||
|
import org.openhab.binding.freeathomesystem.internal.util.FreeAtHomeGeneralException;
|
||||||
|
import org.openhab.binding.freeathomesystem.internal.util.FreeAtHomeHttpCommunicationException;
|
||||||
|
import org.openhab.binding.freeathomesystem.internal.util.UidUtils;
|
||||||
|
import org.openhab.binding.freeathomesystem.internal.valuestateconverter.ValueStateConverter;
|
||||||
|
import org.openhab.core.i18n.LocaleProvider;
|
||||||
|
import org.openhab.core.i18n.TranslationProvider;
|
||||||
|
import org.openhab.core.library.types.StopMoveType;
|
||||||
|
import org.openhab.core.library.types.StringType;
|
||||||
|
import org.openhab.core.thing.Bridge;
|
||||||
|
import org.openhab.core.thing.Channel;
|
||||||
|
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.ThingUID;
|
||||||
|
import org.openhab.core.thing.binding.BaseThingHandler;
|
||||||
|
import org.openhab.core.thing.binding.ThingHandler;
|
||||||
|
import org.openhab.core.thing.binding.builder.ChannelBuilder;
|
||||||
|
import org.openhab.core.thing.binding.builder.ThingBuilder;
|
||||||
|
import org.openhab.core.thing.type.AutoUpdatePolicy;
|
||||||
|
import org.openhab.core.thing.type.ChannelKind;
|
||||||
|
import org.openhab.core.thing.type.ChannelType;
|
||||||
|
import org.openhab.core.thing.type.ChannelTypeBuilder;
|
||||||
|
import org.openhab.core.thing.type.ChannelTypeUID;
|
||||||
|
import org.openhab.core.types.Command;
|
||||||
|
import org.openhab.core.types.RefreshType;
|
||||||
|
import org.openhab.core.types.State;
|
||||||
|
import org.openhab.core.types.StateDescriptionFragmentBuilder;
|
||||||
|
import org.osgi.framework.Bundle;
|
||||||
|
import org.osgi.framework.FrameworkUtil;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link FreeAtHomeDeviceHandler} is responsible for handling the generic free@home device main communication
|
||||||
|
* and thing updates
|
||||||
|
*
|
||||||
|
* @author Andras Uhrin - Initial contribution
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class FreeAtHomeDeviceHandler extends BaseThingHandler implements FreeAtHomeDeviceStateListener {
|
||||||
|
|
||||||
|
private static final String CHANNEL_URI = "channel-type:freeathomesystem:config";
|
||||||
|
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(FreeAtHomeDeviceHandler.class);
|
||||||
|
private FreeAtHomeDeviceDescription device = new FreeAtHomeDeviceDescription();
|
||||||
|
private FreeAtHomeChannelTypeProvider channelTypeProvider;
|
||||||
|
private TranslationProvider i18nProvider;
|
||||||
|
private Locale locale;
|
||||||
|
private Bundle bundle;
|
||||||
|
|
||||||
|
private Map<ChannelUID, FreeAtHomeDatapointGroup> mapChannelUID = new HashMap<ChannelUID, FreeAtHomeDatapointGroup>();
|
||||||
|
private Map<String, ChannelUID> mapEventToChannelUID = new HashMap<String, ChannelUID>();
|
||||||
|
|
||||||
|
public FreeAtHomeDeviceHandler(Thing thing, FreeAtHomeChannelTypeProvider channelTypeProvider,
|
||||||
|
TranslationProvider i18nProvider, LocaleProvider localeProvider) {
|
||||||
|
super(thing);
|
||||||
|
|
||||||
|
this.channelTypeProvider = channelTypeProvider;
|
||||||
|
this.i18nProvider = i18nProvider;
|
||||||
|
this.bundle = FrameworkUtil.getBundle(getClass());
|
||||||
|
this.locale = localeProvider.getLocale();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initialize() {
|
||||||
|
updateStatus(ThingStatus.UNKNOWN);
|
||||||
|
|
||||||
|
scheduler.execute(() -> {
|
||||||
|
FreeAtHomeDeviceHandlerConfiguration config = getConfigAs(FreeAtHomeDeviceHandlerConfiguration.class);
|
||||||
|
|
||||||
|
Bridge bridge = this.getBridge();
|
||||||
|
String locDeviceId = config.deviceId;
|
||||||
|
|
||||||
|
if (bridge != null) {
|
||||||
|
ThingHandler handler = bridge.getHandler();
|
||||||
|
|
||||||
|
if (handler instanceof FreeAtHomeBridgeHandler bridgeHandler) {
|
||||||
|
if (!locDeviceId.isBlank()) {
|
||||||
|
try {
|
||||||
|
device = bridgeHandler.getFreeatHomeDeviceDescription(locDeviceId);
|
||||||
|
|
||||||
|
updateChannels();
|
||||||
|
} catch (FreeAtHomeHttpCommunicationException e) {
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||||
|
"@text/comm-error.error-in-sysap-com");
|
||||||
|
} catch (FreeAtHomeGeneralException e) {
|
||||||
|
logger.debug("General error in the binding - during initialization {}",
|
||||||
|
device.getDeviceId());
|
||||||
|
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
|
||||||
|
"@text/conf-error.general-binding-error");
|
||||||
|
}
|
||||||
|
|
||||||
|
// register device for status updates
|
||||||
|
bridgeHandler.registerDeviceStateListener(device.getDeviceId(), this);
|
||||||
|
|
||||||
|
updateStatus(ThingStatus.ONLINE);
|
||||||
|
|
||||||
|
logger.debug("Device created - device id: {}", device.getDeviceId());
|
||||||
|
} else {
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
|
||||||
|
"@text/conf-error.invalid-deviceconfig");
|
||||||
|
|
||||||
|
logger.debug("Device cannot be created: device ID is null!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.CONFIGURATION_ERROR,
|
||||||
|
"@text/conf-error.bridge-not-configured");
|
||||||
|
|
||||||
|
logger.debug("Device cannot be created: no bridge is configured!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dispose() {
|
||||||
|
Bridge bridge = this.getBridge();
|
||||||
|
|
||||||
|
// Unregister device and specific channel for event based state updated
|
||||||
|
if (bridge != null) {
|
||||||
|
ThingHandler handler = bridge.getHandler();
|
||||||
|
|
||||||
|
if (handler instanceof FreeAtHomeBridgeHandler bridgeHandler) {
|
||||||
|
bridgeHandler.unregisterDeviceStateListener(device.getDeviceId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove mapping tables
|
||||||
|
mapChannelUID.clear();
|
||||||
|
|
||||||
|
mapEventToChannelUID.clear();
|
||||||
|
|
||||||
|
logger.debug("Device removed - device id: {}", device.getDeviceId());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleRefreshCommand(FreeAtHomeBridgeHandler freeAtHomeBridge, FreeAtHomeDatapointGroup dpg,
|
||||||
|
ChannelUID channelUID) {
|
||||||
|
String valueStr = "0";
|
||||||
|
String channelID = "ch000";
|
||||||
|
String datapointID = "0";
|
||||||
|
|
||||||
|
// Check whether it is a INPUT only datapoint group
|
||||||
|
|
||||||
|
if (dpg.getDirection() == FreeAtHomeDatapointGroup.DatapointGroupDirection.INPUT) {
|
||||||
|
FreeAtHomeDatapoint datapoint = dpg.getInputDatapoint();
|
||||||
|
|
||||||
|
if (datapoint != null) {
|
||||||
|
channelID = datapoint.channelId;
|
||||||
|
datapointID = datapoint.getDatapointId();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
FreeAtHomeDatapoint datapoint = dpg.getOutputDatapoint();
|
||||||
|
|
||||||
|
if (datapoint != null) {
|
||||||
|
channelID = datapoint.channelId;
|
||||||
|
datapointID = datapoint.getDatapointId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
valueStr = freeAtHomeBridge.getDatapoint(device.getDeviceId(), channelID, datapointID);
|
||||||
|
|
||||||
|
ValueStateConverter vsc = dpg.getValueStateConverter();
|
||||||
|
|
||||||
|
updateState(channelUID, vsc.convertToState(valueStr));
|
||||||
|
} catch (FreeAtHomeHttpCommunicationException e) {
|
||||||
|
logger.debug("Communication error during refresh command {} - at channel {} - Error string {}",
|
||||||
|
device.getDeviceId(), channelUID.getAsString(), e.getMessage());
|
||||||
|
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||||
|
"@text/comm-error.error-in-sysap-com");
|
||||||
|
} catch (FreeAtHomeGeneralException e) {
|
||||||
|
logger.debug("General error in the binding - during REFRESH command {} - at channel {} - Error string {}",
|
||||||
|
device.getDeviceId(), channelUID.getAsString(), e.getMessage());
|
||||||
|
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
|
||||||
|
"@text/conf-error.general-binding-error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleSetCommand(FreeAtHomeBridgeHandler freeAtHomeBridge, FreeAtHomeDatapointGroup dpg,
|
||||||
|
ChannelUID channelUID, Command command) {
|
||||||
|
State state = null;
|
||||||
|
String valueString = "0";
|
||||||
|
|
||||||
|
// initial error handling. look for the data point group validity
|
||||||
|
FreeAtHomeDatapoint datapoint = dpg.getInputDatapoint();
|
||||||
|
|
||||||
|
if (datapoint == null) {
|
||||||
|
logger.debug("Invalid parameter in handleSetCommand - DeviceId - {} - at channel {}", device.getDeviceId(),
|
||||||
|
channelUID.getAsString());
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
ValueStateConverter vsc = dpg.getValueStateConverter();
|
||||||
|
|
||||||
|
if (command instanceof StopMoveType) {
|
||||||
|
valueString = "0";
|
||||||
|
} else {
|
||||||
|
state = ((State) command);
|
||||||
|
valueString = vsc.convertToValueString(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
freeAtHomeBridge.setDatapoint(device.getDeviceId(), datapoint.channelId, datapoint.getDatapointId(),
|
||||||
|
valueString);
|
||||||
|
|
||||||
|
if (!device.isScene()) {
|
||||||
|
if (state != null) {
|
||||||
|
updateState(channelUID, state);
|
||||||
|
} else {
|
||||||
|
updateState(channelUID, new StringType("STOP"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (FreeAtHomeHttpCommunicationException e) {
|
||||||
|
logger.debug(
|
||||||
|
"Communication error during set command {} - at channel {} - full command {} - Error string {}",
|
||||||
|
device.getDeviceId(), channelUID.getAsString(), command.toFullString(), e.getMessage());
|
||||||
|
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||||
|
"@text/comm-error.error-in-sysap-com");
|
||||||
|
} catch (FreeAtHomeGeneralException e) {
|
||||||
|
logger.debug("General error in the binding - during SET command {} - at channel {} - Error string {}",
|
||||||
|
device.getDeviceId(), channelUID.getAsString(), e.getMessage());
|
||||||
|
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
|
||||||
|
"@text/conf-error.general-binding-error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||||
|
FreeAtHomeBridgeHandler freeAtHomeBridge = null;
|
||||||
|
|
||||||
|
Bridge bridge = this.getBridge();
|
||||||
|
|
||||||
|
if (bridge != null) {
|
||||||
|
ThingHandler handler = bridge.getHandler();
|
||||||
|
|
||||||
|
if (handler instanceof FreeAtHomeBridgeHandler bridgeHandler) {
|
||||||
|
freeAtHomeBridge = bridgeHandler;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (freeAtHomeBridge != null) {
|
||||||
|
updateStatus(ThingStatus.ONLINE);
|
||||||
|
} else {
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.CONFIGURATION_ERROR,
|
||||||
|
"@text/conf-error.invalid-bridge");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
FreeAtHomeDatapointGroup dpg = mapChannelUID.get(channelUID);
|
||||||
|
|
||||||
|
// is the datapointgroup invalid
|
||||||
|
if (dpg == null) {
|
||||||
|
logger.debug("Handle command for device (but invalid datapointgroup) {} - at channel {} - full command {}",
|
||||||
|
device.getDeviceId(), channelUID.getAsString(), command.toFullString());
|
||||||
|
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
|
||||||
|
"@text/conf-error.invalid-deviceconfig");
|
||||||
|
} else {
|
||||||
|
if (command instanceof RefreshType) {
|
||||||
|
handleRefreshCommand(freeAtHomeBridge, dpg, channelUID);
|
||||||
|
} else {
|
||||||
|
handleSetCommand(freeAtHomeBridge, dpg, channelUID, command);
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.debug("Handle command for device {} - at channel {} - full command {}", device.getDeviceId(),
|
||||||
|
channelUID.getAsString(), command.toFullString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onDeviceRemoved() {
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onDeviceStateChanged(String event, String valueString) {
|
||||||
|
// Get the channle UID belonging to this event
|
||||||
|
ChannelUID channelUID = mapEventToChannelUID.get(event);
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (channelUID != null) {
|
||||||
|
// get the value State Converter for the channel
|
||||||
|
FreeAtHomeDatapointGroup dpg = mapChannelUID.get(channelUID);
|
||||||
|
|
||||||
|
if (dpg != null) {
|
||||||
|
State state;
|
||||||
|
state = dpg.getValueStateConverter().convertToState(valueString);
|
||||||
|
|
||||||
|
// Handle state change
|
||||||
|
handleEventBasedUpdate(channelUID, state);
|
||||||
|
|
||||||
|
// if it is virtual device, give a feedback to free@home also
|
||||||
|
if (isThingHandlesVirtualDevice()) {
|
||||||
|
feedbackForVirtualDevice(channelUID, valueString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (FreeAtHomeGeneralException e) {
|
||||||
|
logger.debug("General error in the binding during onDeviceStateChange");
|
||||||
|
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
|
||||||
|
"@text/conf-error.general-binding-error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleEventBasedUpdate(ChannelUID channelUID, State state) {
|
||||||
|
this.updateState(channelUID, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void feedbackForVirtualDevice(ChannelUID channelUID, String valueString) {
|
||||||
|
FreeAtHomeBridgeHandler freeAtHomeBridge = null;
|
||||||
|
|
||||||
|
FreeAtHomeDatapointGroup dpg = mapChannelUID.get(channelUID);
|
||||||
|
|
||||||
|
Bridge bridge = this.getBridge();
|
||||||
|
|
||||||
|
if (bridge != null) {
|
||||||
|
ThingHandler handler = bridge.getHandler();
|
||||||
|
|
||||||
|
if (handler instanceof FreeAtHomeBridgeHandler bridgeHandler) {
|
||||||
|
freeAtHomeBridge = bridgeHandler;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (freeAtHomeBridge == null) {
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE, "@text/gen-error.no-bridge-avail");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dpg == null) {
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
|
||||||
|
"@text/conf-error.datapointgroup-invalid");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
FreeAtHomeDatapoint inputDatapoint = dpg.getInputDatapoint();
|
||||||
|
|
||||||
|
if (inputDatapoint == null) {
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
|
||||||
|
"@text/conf-error.inputdatapoint-invalid");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((dpg.getDirection() != FreeAtHomeDatapointGroup.DatapointGroupDirection.INPUT)
|
||||||
|
|| (dpg.getDirection() != FreeAtHomeDatapointGroup.DatapointGroupDirection.INPUTOUTPUT)) {
|
||||||
|
logger.debug("Handle feedback for virtual device {} - at channel {} - but wrong config",
|
||||||
|
device.getDeviceId(), channelUID.getAsString());
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
freeAtHomeBridge.setDatapoint(device.getDeviceId(), inputDatapoint.channelId,
|
||||||
|
inputDatapoint.getDatapointId(), valueString);
|
||||||
|
|
||||||
|
updateStatus(ThingStatus.ONLINE);
|
||||||
|
|
||||||
|
logger.debug("Handle feedback for virtual device {} - at channel {} - value {}", device.getDeviceId(),
|
||||||
|
channelUID.getAsString(), valueString);
|
||||||
|
} catch (FreeAtHomeHttpCommunicationException e) {
|
||||||
|
logger.debug("Communication error during set command {} - at channel {} - value {} - Error string {}",
|
||||||
|
device.getDeviceId(), channelUID.getAsString(), valueString, e.getMessage());
|
||||||
|
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||||
|
"@text/comm-error.not-able-open-httpconnection");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChannelTypeUID createChannelTypeForDatapointgroup(FreeAtHomeDatapointGroup dpg,
|
||||||
|
ChannelTypeUID channelTypeUID) throws FreeAtHomeGeneralException {
|
||||||
|
StateDescriptionFragmentBuilder stateFragment = StateDescriptionFragmentBuilder.create();
|
||||||
|
|
||||||
|
stateFragment.withReadOnly(dpg.isReadOnly());
|
||||||
|
stateFragment.withPattern(dpg.getTypePattern());
|
||||||
|
|
||||||
|
if (dpg.isDecimal() || dpg.isInteger()) {
|
||||||
|
BigDecimal min = new BigDecimal(dpg.getMin());
|
||||||
|
BigDecimal max = new BigDecimal(dpg.getMax());
|
||||||
|
stateFragment.withMinimum(min).withMaximum(max);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
URI configDescriptionUriChannel = new URI(CHANNEL_URI);
|
||||||
|
|
||||||
|
ChannelTypeBuilder<?> channelTypeBuilder = ChannelTypeBuilder
|
||||||
|
.state(channelTypeUID,
|
||||||
|
String.format("%s-%s-%s-%s", dpg.getLabel(), dpg.getOpenHabItemType(),
|
||||||
|
dpg.getOpenHabCategory(), "type"),
|
||||||
|
dpg.getOpenHabItemType())
|
||||||
|
.withCategory(dpg.getOpenHabCategory()).withStateDescriptionFragment(stateFragment.build());
|
||||||
|
|
||||||
|
ChannelType channelType = channelTypeBuilder.isAdvanced(false)
|
||||||
|
.withConfigDescriptionURI(configDescriptionUriChannel)
|
||||||
|
.withDescription(String.format("Type for channel - %s ", dpg.getLabel())).build();
|
||||||
|
|
||||||
|
channelTypeProvider.addChannelType(channelType);
|
||||||
|
|
||||||
|
logger.debug("Channel type created {} - label: {} - category: {}", channelTypeUID.getAsString(),
|
||||||
|
dpg.getLabel(), dpg.getOpenHabCategory());
|
||||||
|
} catch (URISyntaxException e) {
|
||||||
|
logger.debug("Channel config URI cannot created for datapoint - datapoint group: {}", dpg.getLabel());
|
||||||
|
}
|
||||||
|
|
||||||
|
return channelTypeUID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateChannels() throws FreeAtHomeGeneralException {
|
||||||
|
// define update policy
|
||||||
|
AutoUpdatePolicy policy = AutoUpdatePolicy.DEFAULT;
|
||||||
|
|
||||||
|
if (device.isScene()) {
|
||||||
|
policy = AutoUpdatePolicy.VETO;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize channels
|
||||||
|
List<Channel> thingChannels = new ArrayList<>(this.getThing().getChannels());
|
||||||
|
|
||||||
|
if (thingChannels.isEmpty()) {
|
||||||
|
ThingBuilder thingBuilder = editThing();
|
||||||
|
|
||||||
|
ThingUID thingUID = thing.getUID();
|
||||||
|
|
||||||
|
for (int i = 0; i < device.getNumberOfChannels(); i++) {
|
||||||
|
FreeAtHomeDeviceChannel channel = device.getChannel(i);
|
||||||
|
|
||||||
|
for (int j = 0; j < channel.getNumberOfDatapointGroup(); j++) {
|
||||||
|
FreeAtHomeDatapointGroup dpg = channel.getDatapointGroup(j);
|
||||||
|
Map<String, String> channelProps = new HashMap<>();
|
||||||
|
|
||||||
|
FreeAtHomeDatapoint inputDatapoint = dpg.getInputDatapoint();
|
||||||
|
FreeAtHomeDatapoint outputDatapoint = dpg.getOutputDatapoint();
|
||||||
|
|
||||||
|
if (inputDatapoint != null) {
|
||||||
|
channelProps.put("input", inputDatapoint.getDatapointId());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (outputDatapoint != null) {
|
||||||
|
channelProps.put("output", outputDatapoint.getDatapointId());
|
||||||
|
}
|
||||||
|
|
||||||
|
ChannelTypeUID channelTypeUID = UidUtils.generateChannelTypeUID(dpg.getValueType(),
|
||||||
|
dpg.isReadOnly());
|
||||||
|
|
||||||
|
if (channelTypeProvider.getChannelType(channelTypeUID, null) == null) {
|
||||||
|
channelTypeUID = createChannelTypeForDatapointgroup(dpg, channelTypeUID);
|
||||||
|
}
|
||||||
|
|
||||||
|
ChannelUID channelUID = new ChannelUID(thingUID, channel.getChannelId(),
|
||||||
|
dpg.getLabel().substring(4));
|
||||||
|
|
||||||
|
String channelLabel = String.format("%s",
|
||||||
|
i18nProvider.getText(bundle, dpg.getLabel(), "-", locale));
|
||||||
|
|
||||||
|
String channelDescription = String.format("(%s) %s", channel.getChannelLabel(),
|
||||||
|
i18nProvider.getText(bundle, dpg.getDescription(), "-", locale));
|
||||||
|
|
||||||
|
Channel thingChannel = ChannelBuilder.create(channelUID)
|
||||||
|
.withAcceptedItemType(dpg.getOpenHabItemType()).withKind(ChannelKind.STATE)
|
||||||
|
.withProperties(channelProps).withLabel(capitalizeWordsInLabel(channelLabel))
|
||||||
|
.withDescription(channelDescription).withType(channelTypeUID).withAutoUpdatePolicy(policy)
|
||||||
|
.build();
|
||||||
|
thingChannels.add(thingChannel);
|
||||||
|
|
||||||
|
logger.debug("Thing channel created - device: {} - channelUID: {} - channel label: {}",
|
||||||
|
device.getDeviceId() + device.getDeviceLabel(), channelUID.getAsString(), channelLabel);
|
||||||
|
|
||||||
|
// in case of output channel, register it for updates
|
||||||
|
if (outputDatapoint != null) {
|
||||||
|
String eventDatapointID = new String(device.getDeviceId() + "/" + channel.getChannelId() + "/"
|
||||||
|
+ outputDatapoint.getDatapointId());
|
||||||
|
|
||||||
|
mapEventToChannelUID.put(eventDatapointID, channelUID);
|
||||||
|
}
|
||||||
|
|
||||||
|
// add the datapoint group to the mapping channel
|
||||||
|
mapChannelUID.put(channelUID, dpg);
|
||||||
|
|
||||||
|
if (dpg.getInputDatapoint() == null) {
|
||||||
|
logger.debug(
|
||||||
|
"Thing channel registered - device: {} - channelUID: {} - channel label: {} - category: {}",
|
||||||
|
device.getDeviceId() + device.getDeviceLabel(), channelUID.getAsString(),
|
||||||
|
dpg.getLabel(), dpg.getOpenHabCategory());
|
||||||
|
} else {
|
||||||
|
logger.debug(
|
||||||
|
"Thing channel registered - device: {} - channelUID: {} - channel label: {} - category: {}",
|
||||||
|
device.getDeviceId() + device.getDeviceLabel(), channelUID.getAsString(),
|
||||||
|
dpg.getLabel(), dpg.getOpenHabCategory());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
thingBuilder.withChannels(thingChannels);
|
||||||
|
|
||||||
|
updateThing(thingBuilder.build());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
reloadChannelTypes();
|
||||||
|
}
|
||||||
|
|
||||||
|
thingChannels.forEach(channel -> {
|
||||||
|
if (isLinked(channel.getUID())) {
|
||||||
|
channelLinked(channel.getUID());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void reloadChannelTypes() throws FreeAtHomeGeneralException {
|
||||||
|
Bridge bridge = this.getBridge();
|
||||||
|
|
||||||
|
ThingUID thingUID = thing.getUID();
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (bridge != null) {
|
||||||
|
ThingHandler handler = bridge.getHandler();
|
||||||
|
|
||||||
|
if (handler instanceof FreeAtHomeBridgeHandler bridgeHandler) {
|
||||||
|
device = bridgeHandler.getFreeatHomeDeviceDescription(device.getDeviceId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (FreeAtHomeHttpCommunicationException e) {
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||||
|
"@text/comm-error.error-in-sysap-com");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < device.getNumberOfChannels(); i++) {
|
||||||
|
FreeAtHomeDeviceChannel channel = device.getChannel(i);
|
||||||
|
|
||||||
|
for (int j = 0; j < channel.getNumberOfDatapointGroup(); j++) {
|
||||||
|
FreeAtHomeDatapointGroup dpg = channel.getDatapointGroup(j);
|
||||||
|
|
||||||
|
ChannelTypeUID channelTypeUID = UidUtils.generateChannelTypeUID(dpg.getValueType(), dpg.isReadOnly());
|
||||||
|
|
||||||
|
if (channelTypeProvider.getChannelType(channelTypeUID, null) == null) {
|
||||||
|
channelTypeUID = createChannelTypeForDatapointgroup(dpg, channelTypeUID);
|
||||||
|
}
|
||||||
|
|
||||||
|
ChannelUID channelUID = new ChannelUID(thingUID, channel.getChannelId());
|
||||||
|
|
||||||
|
FreeAtHomeDatapoint outputDatapoint = dpg.getOutputDatapoint();
|
||||||
|
|
||||||
|
// in case of output channel, register it for updates
|
||||||
|
if (outputDatapoint != null) {
|
||||||
|
String eventDatapointID = new String(device.getDeviceId() + "/" + channel.getChannelId() + "/"
|
||||||
|
+ outputDatapoint.getDatapointId());
|
||||||
|
|
||||||
|
mapEventToChannelUID.put(eventDatapointID, channelUID);
|
||||||
|
}
|
||||||
|
|
||||||
|
// add the datapoint group to the mapping channel
|
||||||
|
mapChannelUID.put(channelUID, dpg);
|
||||||
|
|
||||||
|
logger.debug("Thing channelType reloaded - Device: {} - channelTypeUID: {}",
|
||||||
|
device.getDeviceId() + device.getDeviceLabel(), channelTypeUID.getAsString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeChannels() {
|
||||||
|
Bridge bridge = this.getBridge();
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (bridge != null) {
|
||||||
|
ThingHandler handler = bridge.getHandler();
|
||||||
|
|
||||||
|
if (handler instanceof FreeAtHomeBridgeHandler bridgeHandler) {
|
||||||
|
device = bridgeHandler.getFreeatHomeDeviceDescription(device.getDeviceId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (FreeAtHomeHttpCommunicationException e) {
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||||
|
"@text/comm-error.error-in-sysap-com");
|
||||||
|
}
|
||||||
|
|
||||||
|
mapChannelUID.clear();
|
||||||
|
|
||||||
|
mapEventToChannelUID.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String capitalizeWordsInLabel(String label) {
|
||||||
|
// splliting up words using split function
|
||||||
|
String[] words = label.split(" ");
|
||||||
|
|
||||||
|
for (int i = 0; i < words.length; i++) {
|
||||||
|
|
||||||
|
// taking letter individually from sentences
|
||||||
|
String firstLetter = words[i].substring(0, 1);
|
||||||
|
String restOfWord = words[i].substring(1);
|
||||||
|
|
||||||
|
// making first letter uppercase using toUpperCase function
|
||||||
|
firstLetter = firstLetter.toUpperCase();
|
||||||
|
words[i] = firstLetter + restOfWord;
|
||||||
|
}
|
||||||
|
|
||||||
|
// joining the words together to make a sentence
|
||||||
|
return String.join(" ", words);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isThingHandlesVirtualDevice() {
|
||||||
|
return device.isVirtual();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2024 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.freeathomesystem.internal.handler;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link FreeAtHomeDeviceStateListener} is responsible for response the device state changes from SysAp
|
||||||
|
* and thing updates
|
||||||
|
*
|
||||||
|
* @author Andras Uhrin - Initial contribution
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public interface FreeAtHomeDeviceStateListener {
|
||||||
|
void onDeviceRemoved();
|
||||||
|
|
||||||
|
void onDeviceStateChanged(String event, String valueString);
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2024 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.freeathomesystem.internal.type;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.openhab.core.thing.type.ChannelType;
|
||||||
|
import org.openhab.core.thing.type.ChannelTypeProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Andras Uhrin - Initial contribution
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public interface FreeAtHomeChannelTypeProvider extends ChannelTypeProvider {
|
||||||
|
|
||||||
|
public void addChannelType(ChannelType channelType);
|
||||||
|
}
|
@ -0,0 +1,65 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2024 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.freeathomesystem.internal.type;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
import org.openhab.core.thing.type.ChannelType;
|
||||||
|
import org.openhab.core.thing.type.ChannelTypeProvider;
|
||||||
|
import org.openhab.core.thing.type.ChannelTypeUID;
|
||||||
|
import org.osgi.service.component.annotations.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Andras Uhrin - Initial contribution
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Component(service = { FreeAtHomeChannelTypeProvider.class, ChannelTypeProvider.class })
|
||||||
|
@NonNullByDefault
|
||||||
|
public class FreeAtHomeChannelTypeProviderImpl implements FreeAtHomeChannelTypeProvider {
|
||||||
|
|
||||||
|
private final Map<ChannelTypeUID, ChannelType> channelTypesByUID = new HashMap<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<ChannelType> getChannelTypes(@Nullable Locale locale) {
|
||||||
|
Collection<ChannelType> result = new ArrayList<>();
|
||||||
|
|
||||||
|
for (ChannelTypeUID uid : channelTypesByUID.keySet()) {
|
||||||
|
ChannelType channelType = channelTypesByUID.get(uid);
|
||||||
|
|
||||||
|
if (channelType != null) {
|
||||||
|
result.add(channelType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable ChannelType getChannelType(@Nullable ChannelTypeUID channelTypeUID, @Nullable Locale locale) {
|
||||||
|
return channelTypesByUID.get(channelTypeUID);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addChannelType(@Nullable ChannelType channelType) {
|
||||||
|
if (channelType != null) {
|
||||||
|
channelTypesByUID.put(channelType.getUID(), channelType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2024 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.freeathomesystem.internal.type;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.openhab.core.thing.binding.ThingTypeProvider;
|
||||||
|
import org.openhab.core.thing.type.ThingType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Andras Uhrin - Initial contribution
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public interface FreeAtHomeThingTypeProvider extends ThingTypeProvider {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the ThingType to this provider.
|
||||||
|
*/
|
||||||
|
public void addThingType(ThingType thingType);
|
||||||
|
}
|
@ -0,0 +1,55 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2024 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.freeathomesystem.internal.type;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
import org.openhab.core.thing.ThingTypeUID;
|
||||||
|
import org.openhab.core.thing.binding.ThingTypeProvider;
|
||||||
|
import org.openhab.core.thing.type.ThingType;
|
||||||
|
import org.osgi.service.component.annotations.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Andras Uhrin - Initial contribution
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Component(service = { FreeAtHomeThingTypeProvider.class, ThingTypeProvider.class })
|
||||||
|
@NonNullByDefault
|
||||||
|
public class FreeAtHomeThingTypeProviderImpl implements FreeAtHomeThingTypeProvider {
|
||||||
|
private final Map<ThingTypeUID, ThingType> thingTypesByUID = new HashMap<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<ThingType> getThingTypes(@Nullable Locale locale) {
|
||||||
|
Map<ThingTypeUID, ThingType> copy = new HashMap<>(thingTypesByUID);
|
||||||
|
return copy.values();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable ThingType getThingType(ThingTypeUID thingTypeUID, @Nullable Locale locale) {
|
||||||
|
return thingTypesByUID.get(thingTypeUID);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addThingType(@Nullable ThingType thingType) {
|
||||||
|
if (thingType != null) {
|
||||||
|
thingTypesByUID.put(thingType.getUID(), thingType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,362 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2024 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.freeathomesystem.internal.util;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link FidTranslationUtils} having constant values for json parsing
|
||||||
|
*
|
||||||
|
* @author Andras Uhrin - Initial contribution
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class FidTranslationUtils {
|
||||||
|
|
||||||
|
public static final int FID_UNKNOWN = 0xFFFFAAFF; // Unknown
|
||||||
|
|
||||||
|
// free@home constants
|
||||||
|
public static final int FID_SWITCH_SENSOR = 0x0000; // Control element
|
||||||
|
public static final int FID_DIMMING_SENSOR = 0x0001; // Dimming sensor
|
||||||
|
public static final int FID_BLIND_SENSOR = 0x0003; // Blind sensor
|
||||||
|
public static final int FID_STAIRCASE_LIGHT_SENSOR = 0x0004; // Stairwell light sensor
|
||||||
|
public static final int FID_FORCE_ON_OFF_SENSOR = 0x0005; // Force On/Off sensor
|
||||||
|
public static final int FID_SCENE_SENSOR = 0x0006; // Scene sensor
|
||||||
|
public static final int FID_SWITCH_ACTUATOR = 0x0007; // Switch actuator
|
||||||
|
public static final int FID_SHUTTER_ACTUATOR = 0x0009; // Blind actuator
|
||||||
|
public static final int FID_ROOM_TEMPERATURE_CONTROLLER_MASTER_WITH_FAN = 0x000A; // Room temperature controller
|
||||||
|
// with fan speed level
|
||||||
|
public static final int FID_ROOM_TEMPERATURE_CONTROLLER_SLAVE = 0x000B; // Room temperature controller extension
|
||||||
|
// unit
|
||||||
|
public static final int FID_WIND_ALARM_SENSOR = 0x000C; // Wind Alarm
|
||||||
|
public static final int FID_FROST_ALARM_SENSOR = 0x000D; // Frost Alarm
|
||||||
|
public static final int FID_RAIN_ALARM_SENSOR = 0x000E; // Rain Alarm
|
||||||
|
public static final int FID_WINDOW_DOOR_SENSOR = 0x000F; // Window sensor
|
||||||
|
public static final int FID_MOVEMENT_DETECTOR = 0x0011; // Movement Detector
|
||||||
|
public static final int FID_DIMMING_ACTUATOR = 0x0012; // Dim actuator
|
||||||
|
public static final int FID_RADIATOR_ACTUATOR = 0x0014; // Radiator
|
||||||
|
public static final int FID_UNDERFLOOR_HEATING = 0x0015; // Underfloor heating
|
||||||
|
public static final int FID_FAN_COIL = 0x0016; // Fan Coil
|
||||||
|
public static final int FID_TWO_LEVEL_CONTROLLER = 0x0017; // Two-level controller
|
||||||
|
public static final int FID_DES_DOOR_OPENER_ACTUATOR = 0x001A; // Door opener
|
||||||
|
public static final int FID_PROXY = 0x001B; // Proxy
|
||||||
|
public static final int FID_DES_LEVEL_CALL_ACTUATOR = 0x001D; // Door Map.entry System Call Level Actuator
|
||||||
|
public static final int FID_DES_LEVEL_CALL_SENSOR = 0x001E; // Door Map.entry System Call Level Sensor
|
||||||
|
public static final int FID_DES_DOOR_RINGING_SENSOR = 0x001F; // Door call
|
||||||
|
public static final int FID_DES_AUTOMATIC_DOOR_OPENER_ACTUATOR = 0x0020; // Automatic door opener
|
||||||
|
public static final int FID_DES_LIGHT_SWITCH_ACTUATOR = 0x0021; // Corridor light
|
||||||
|
public static final int FID_ROOM_TEMPERATURE_CONTROLLER_MASTER_WITHOUT_FAN = 0x0023; // Room temperature controller
|
||||||
|
public static final int FID_COOLING_ACTUATOR = 0x0024; // Cooling mode
|
||||||
|
public static final int FID_HEATING_ACTUATOR = 0x0027; // Heating mode
|
||||||
|
public static final int FID_FORCE_UP_DOWN_SENSOR = 0x0028; // Force-position blind
|
||||||
|
public static final int FID_HEATING_COOLING_ACTUATOR = 0x0029; // Auto. heating/cooling mode
|
||||||
|
public static final int FID_HEATING_COOLING_SENSOR = 0x002A; // Switchover heating/cooling
|
||||||
|
public static final int FID_DES_DEVICE_SETTINGS = 0x002B; // Device settings
|
||||||
|
public static final int FID_RGB_W_ACTUATOR = 0x002E; // Dim actuator
|
||||||
|
public static final int FID_RGB_ACTUATOR = 0x002F; // Dim actuator
|
||||||
|
public static final int FID_PANEL_SWITCH_SENSOR = 0x0030; // Control element
|
||||||
|
public static final int FID_PANEL_DIMMING_SENSOR = 0x0031; // Dimming sensor
|
||||||
|
public static final int FID_PANEL_BLIND_SENSOR = 0x0033; // Blind sensor
|
||||||
|
public static final int FID_PANEL_STAIRCASE_LIGHT_SENSOR = 0x0034; // Stairwell light sensor
|
||||||
|
public static final int FID_PANEL_FORCE_ON_OFF_SENSOR = 0x0035; // Force On/Off sensor
|
||||||
|
public static final int FID_PANEL_FORCE_UP_DOWN_SENSOR = 0x0036; // Force-position blind
|
||||||
|
public static final int FID_PANEL_SCENE_SENSOR = 0x0037; // Scene sensor
|
||||||
|
public static final int FID_PANEL_ROOM_TEMPERATURE_CONTROLLER_SLAVE = 0x0038; // Room temperature controller
|
||||||
|
// extension unit
|
||||||
|
public static final int FID_PANEL_FAN_COIL_SENSOR = 0x0039; // Fan coil sensor
|
||||||
|
public static final int FID_PANEL_RGB_CT_SENSOR = 0x003A; // RGB + warm white/cold white sensor
|
||||||
|
public static final int FID_PANEL_RGB_SENSOR = 0x003B; // RGB sensor
|
||||||
|
public static final int FID_PANEL_CT_SENSOR = 0x003C; // Warm white/cold white sensor
|
||||||
|
public static final int FID_ADDITIONAL_HEATING_ACTUATOR = 0x003D; // Add. stage for heating mode
|
||||||
|
public static final int FID_RADIATOR_ACTUATOR_MASTER = 0x003E; // Radiator thermostate
|
||||||
|
public static final int FID_RADIATOR_ACTUATOR_SLAVE = 0x003F; // Room temperature controller extension unit
|
||||||
|
public static final int FID_BRIGHTNESS_SENSOR = 0x0041; // Brightness sensor
|
||||||
|
public static final int FID_RAIN_SENSOR = 0x0042; // Rain sensor
|
||||||
|
public static final int FID_TEMPERATURE_SENSOR = 0x0043; // Temperature sensor
|
||||||
|
public static final int FID_WIND_SENSOR = 0x0044; // Wind sensor
|
||||||
|
public static final int FID_TRIGGER = 0x0045; // Trigger
|
||||||
|
public static final int FID_FCA_2_PIPE_HEATING = 0x0047; // Heating mode
|
||||||
|
public static final int FID_FCA_2_PIPE_COOLING = 0x0048; // Cooling mode
|
||||||
|
public static final int FID_FCA_2_PIPE_HEATING_COOLING = 0x0049; // Auto. heating/cooling mode
|
||||||
|
public static final int FID_FCA_4_PIPE_HEATING_AND_COOLING = 0x004A; // Two valves for heating and cooling
|
||||||
|
public static final int FID_WINDOW_DOOR_ACTUATOR = 0x004B; // Window/Door
|
||||||
|
public static final int FID_INVERTER_INFO = 0x004E; // ABC
|
||||||
|
public static final int FID_METER_INFO = 0x004F; // ABD
|
||||||
|
public static final int FID_BATTERY_INFO = 0x0050; // ACD
|
||||||
|
public static final int FID_PANEL_TIMER_PROGRAM_SWITCH_SENSOR = 0x0051; // Timer program switch sensor
|
||||||
|
public static final int FID_DOMUSTECH_ZONE = 0x0055; // Zone
|
||||||
|
public static final int FID_CENTRAL_HEATING_ACTUATOR = 0x0056; // Central heating actuator
|
||||||
|
public static final int FID_CENTRAL_COOLING_ACTUATOR = 0x0057; // Central cooling actuator
|
||||||
|
public static final int FID_HOUSE_KEEPING = 0x0059; // Housekeeping
|
||||||
|
public static final int FID_MEDIA_PLAYER = 0x005A; // Media Player
|
||||||
|
public static final int FID_PANEL_ROOM_TEMPERATURE_CONTROLLER_SLAVE_FOR_BATTERY_DEVICE = 0x005B; // Panel Room
|
||||||
|
// Temperature
|
||||||
|
// Controller Slave
|
||||||
|
// For Battery
|
||||||
|
// Device
|
||||||
|
public static final int FID_PANEL_MEDIA_PLAYER_SENSOR = 0x0060; // Media Player Sensor
|
||||||
|
public static final int FID_BLIND_ACTUATOR = 0x0061; // Roller blind actuator
|
||||||
|
public static final int FID_ATTIC_WINDOW_ACTUATOR = 0x0062; // Attic window actuator
|
||||||
|
public static final int FID_AWNING_ACTUATOR = 0x0063; // Awning actuator
|
||||||
|
public static final int FID_WINDOW_DOOR_POSITION_SENSOR = 0x0064; // WindowDoor Position Sensor
|
||||||
|
public static final int FID_WINDOW_DOOR_POSITION_ACTUATOR = 0x0065; // Window/Door position
|
||||||
|
public static final int FID_MEDIA_PLAYBACK_CONTROL_SENSOR = 0x0066; // Media playback control sensor
|
||||||
|
public static final int FID_MEDIA_VOLUME_SENSOR = 0x0067; // Media volume sensor
|
||||||
|
public static final int FID_DISHWASHER = 0x0068; // Dishwasher
|
||||||
|
public static final int FID_LAUNDRY = 0x0069; // Laundry
|
||||||
|
public static final int FID_DRYER = 0x006A; // Dryer
|
||||||
|
public static final int FID_OVEN = 0x006B; // Oven
|
||||||
|
public static final int FID_FRIDGE = 0x006C; // Fridge
|
||||||
|
public static final int FID_FREEZER = 0x006D; // Freezer
|
||||||
|
public static final int FID_HOOD = 0x006E; // Hood
|
||||||
|
public static final int FID_COFFEE_MACHINE = 0x006F; // Coffee machine
|
||||||
|
public static final int FID_FRIDGE_FREEZER = 0x0070; // Fridge/Freezer
|
||||||
|
public static final int FID_TIMER_PROGRAM_OR_ALERT_SWITCH_SENSOR = 0x0071; // Timer program switch sensor
|
||||||
|
public static final int FID_CEILING_FAN_ACTUATOR = 0x0073; // Ceiling fan actuator
|
||||||
|
public static final int FID_CEILING_FAN_SENSOR = 0x0074; // Ceiling fan sensor
|
||||||
|
public static final int FID_SPLIT_UNIT_GATEWAY = 0x0075; // Room temperature controller with fan speed level
|
||||||
|
public static final int FID_ZONE = 0x0076; // Zone
|
||||||
|
public static final int FID_24H_ZONE = 0x0077; // Safety
|
||||||
|
public static final int FID_EXTERNAL_IR_SENSOR_BX80 = 0x0078; // External IR Sensor BX80
|
||||||
|
public static final int FID_EXTERNAL_IR_SENSOR_VXI = 0x0079; // External IR Sensor VXI
|
||||||
|
public static final int FID_EXTERNAL_IR_SENSOR_MINI = 0x007A; // External IR Sensor Mini
|
||||||
|
public static final int FID_EXTERNAL_IR_SENSOR_HIGH_ALTITUDE = 0x007B; // External IR Sensor High Altitude
|
||||||
|
public static final int FID_EXTERNAL_IR_SENSOR_CURTAIN = 0x007C; // External IR Sensor Curtain
|
||||||
|
public static final int FID_SMOKE_DETECTOR = 0x007D; // Smoke Detector
|
||||||
|
public static final int FID_CARBON_MONOXIDE_SENSOR = 0x007E; // Carbon Monoxide Sensor
|
||||||
|
public static final int FID_METHANE_DETECTOR = 0x007F; // Methane Detector
|
||||||
|
public static final int FID_GAS_SENSOR_LPG = 0x0080; // Gas Sensor LPG
|
||||||
|
public static final int FID_FLOOD_DETECTION = 0x0081; // Flood Detection
|
||||||
|
public static final int FID_DOMUS_CENTRAL_UNIT_NEXTGEN = 0x0082; // secure@home Central Unit
|
||||||
|
public static final int FID_THERMOSTAT = 0x0083; // Thermostat
|
||||||
|
public static final int FID_PANEL_DOMUS_ZONE_SENSOR = 0x0084; // secure@home Zone Sensor
|
||||||
|
public static final int FID_THERMOSTAT_SLAVE = 0x0085; // Slave thermostat
|
||||||
|
public static final int FID_DOMUS_SECURE_INTEGRATION = 0x0086; // secure@home Integration Logic
|
||||||
|
public static final int FID_ADDITIONAL_COOLING_ACTUATOR = 0x0087; // Add. stage for cooling mode
|
||||||
|
public static final int FID_TWO_LEVEL_HEATING_ACTUATOR = 0x0088; // Two Level Heating Actuator
|
||||||
|
public static final int FID_TWO_LEVEL_COOLING_ACTUATOR = 0x0089; // Two Level Cooling Actuator
|
||||||
|
public static final int FID_GLOBAL_ZONE = 0x008E; // Zone
|
||||||
|
public static final int FID_VOLUME_UP_SENSOR = 0x008F; // Volume up
|
||||||
|
public static final int FID_VOLUME_DOWN_SENSOR = 0x0090; // Volume down
|
||||||
|
public static final int FID_PLAY_PAUSE_SENSOR = 0x0091; // Play/pause
|
||||||
|
public static final int FID_NEXT_FAVORITE_SENSOR = 0x0092; // Next favorite
|
||||||
|
public static final int FID_NEXT_SONG_SENSOR = 0x0093; // Next song
|
||||||
|
public static final int FID_PREVIOUS_SONG_SENSOR = 0x0094; // Previous song
|
||||||
|
public static final int FID_HOME_APPLIANCE_SENSOR = 0x0095; // Home appliance sensor
|
||||||
|
public static final int FID_HEAT_SENSOR = 0x0096; // Heat sensor
|
||||||
|
public static final int FID_ZONE_SWITCHING = 0x0097; // Zone switching
|
||||||
|
public static final int FID_SECURE_AT_HOME_FUNCTION = 0x0098; // Button function
|
||||||
|
public static final int FID_COMPLEX_CONFIGURATION = 0x0099; // Advanced configuration
|
||||||
|
public static final int FID_DOMUS_CENTRAL_UNIT_BASIC = 0x009A; // secure@home Central Unit Basic
|
||||||
|
public static final int FID_DOMUS_REPEATER = 0x009B; // Repeater
|
||||||
|
public static final int FID_DOMUS_SCENE_TRIGGER = 0x009C; // Remote scene control
|
||||||
|
public static final int FID_DOMUSWINDOWCONTACT = 0x009D; // Window sensor
|
||||||
|
public static final int FID_DOMUSMOVEMENTDETECTOR = 0x009E; // Movement Detector
|
||||||
|
public static final int FID_DOMUSCURTAINDETECTOR = 0x009F; // External IR Sensor Curtain
|
||||||
|
public static final int FID_DOMUSSMOKEDETECTOR = 0x00A0; // Smoke Detector
|
||||||
|
public static final int FID_DOMUSFLOODDETECTOR = 0x00A1; // Flood Detection
|
||||||
|
public static final int FID_PANEL_SUG_SENSOR = 0x00A3; // Sensor for air-conditioning unit
|
||||||
|
public static final int FID_TWO_LEVEL_HEATING_COOLING_ACTUATOR = 0x00A4; // Two-point controller for heating or
|
||||||
|
// cooling
|
||||||
|
public static final int FID_PANEL_THERMOSTAT_CONTROLLER_SLAVE = 0x00A5; // Slave thermostat
|
||||||
|
public static final int FID_WALLBOX = 0x00A6; // Wallbox
|
||||||
|
public static final int FID_PANEL_WALLBOX = 0x00A7; // Wallbox
|
||||||
|
public static final int FID_DOOR_LOCK_CONTROL = 0x00A8; // Door lock control
|
||||||
|
public static final int FID_VRV_GATEWAY = 0x00AA; // Room temperature controller with fan speed level
|
||||||
|
|
||||||
|
public static final int FID_SCENE_TRIGGER = 0x4800; // Scene trigger
|
||||||
|
public static final int FID_RULE_SWITCH = 0x4A00; // Scene trigger
|
||||||
|
|
||||||
|
// FID added based on tests
|
||||||
|
public static final int FID_AIRQUALITYSENSOR_PRESSURE = 0x0E017;
|
||||||
|
public static final int FID_AIRQUALITYSENSOR_CO2 = 0x0E018;
|
||||||
|
public static final int FID_AIRQUALITYSENSOR_CO = 0x0E019;
|
||||||
|
public static final int FID_AIRQUALITYSENSOR_NO2 = 0x0E01A;
|
||||||
|
public static final int FID_AIRQUALITYSENSOR_O3 = 0x0E01B;
|
||||||
|
public static final int FID_AIRQUALITYSENSOR_PM10 = 0x0E01C;
|
||||||
|
public static final int FID_AIRQUALITYSENSOR_PM25 = 0x0E01D;
|
||||||
|
public static final int FID_AIRQUALITYSENSOR_VOC = 0x0E01E;
|
||||||
|
public static final int FID_AIRQUALITYSENSOR_HUMIDITY = 0x0B03F;
|
||||||
|
|
||||||
|
public static final int FID_MOVEMENT_DETECTOR_FLEX = 0x1090;
|
||||||
|
public static final int FID_DIMMING_ACTUATOR_FLEX = 0x1810;
|
||||||
|
|
||||||
|
private static final Map<String, String> MAP_FUNCTION_ID = Map.ofEntries(Map.entry("0x0000", "fid-control-element"), // FID_SWITCH_SENSOR
|
||||||
|
Map.entry("0x0001", "fid-dimming-sensor"), // FID_DIMMING_SENSOR
|
||||||
|
Map.entry("0x0003", "fid-blind-sensor"), // FID_BLIND_SENSOR
|
||||||
|
Map.entry("0x0004", "fid-stairwell-light-sensor"), // FID_STAIRCASE_LIGHT_SENSOR
|
||||||
|
Map.entry("0x0005", "fid-force-on/off-sensor"), // FID_FORCE_ON_OFF_SENSOR
|
||||||
|
Map.entry("0x0006", "fid-scene-sensor"), // FID_SCENE_SENSOR
|
||||||
|
Map.entry("0x0007", "fid-switch-actuator"), // FID_SWITCH_ACTUATOR
|
||||||
|
Map.entry("0x0009", "fid-blind-actuator"), // FID_SHUTTER_ACTUATOR
|
||||||
|
Map.entry("0x000A", "fid-room-temperature-controller-with-fan-speed-level"), // FID_ROOM_TEMPERATURE_CONTROLLER_MASTER_WITH_FAN
|
||||||
|
Map.entry("0x000B", "fid-room-temperature-controller-extension-unit"), // FID_ROOM_TEMPERATURE_CONTROLLER_SLAVE
|
||||||
|
Map.entry("0x000C", "fid-wind-alarm"), // FID_WIND_ALARM_SENSOR
|
||||||
|
Map.entry("0x000D", "fid-frost-alarm"), // FID_FROST_ALARM_SENSOR
|
||||||
|
Map.entry("0x000E", "fid-rain-alarm"), // FID_RAIN_ALARM_SENSOR
|
||||||
|
Map.entry("0x000F", "fid-window-sensor"), // FID_WINDOW_DOOR_SENSOR
|
||||||
|
Map.entry("0x0011", "fid-movement-detector"), // FID_MOVEMENT_DETECTOR
|
||||||
|
Map.entry("0x0012", "fid-dim-actuator"), // FID_DIMMING_ACTUATOR
|
||||||
|
Map.entry("0x0014", "fid-radiator"), // FID_RADIATOR_ACTUATOR
|
||||||
|
Map.entry("0x0015", "fid-underfloor-heating"), // FID_UNDERFLOOR_HEATING
|
||||||
|
Map.entry("0x0016", "fid-fan-coil"), // FID_FAN_COIL
|
||||||
|
Map.entry("0x0017", "fid-two-level-controller"), // FID_TWO_LEVEL_CONTROLLER
|
||||||
|
Map.entry("0x001A", "fid-door-opener"), // FID_DES_DOOR_OPENER_ACTUATOR
|
||||||
|
Map.entry("0x001B", "fid-proxy"), // FID_PROXY
|
||||||
|
Map.entry("0x001D", "fid-door-map.entry-system-call-level-actuator"), // FID_DES_LEVEL_CALL_ACTUATOR
|
||||||
|
Map.entry("0x001E", "fid-door-map.entry-system-call-level-sensor"), // FID_DES_LEVEL_CALL_SENSOR
|
||||||
|
Map.entry("0x001F", "fid-door-call"), // FID_DES_DOOR_RINGING_SENSOR
|
||||||
|
Map.entry("0x0020", "fid-automatic-door-opener"), // FID_DES_AUTOMATIC_DOOR_OPENER_ACTUATOR
|
||||||
|
Map.entry("0x0021", "fid-corridor-light"), // FID_DES_LIGHT_SWITCH_ACTUATOR
|
||||||
|
Map.entry("0x0023", "fid-room-temperature-controller"), // FID_ROOM_TEMPERATURE_CONTROLLER_MASTER_WITHOUT_FAN
|
||||||
|
Map.entry("0x0024", "fid-cooling-mode"), // FID_COOLING_ACTUATOR
|
||||||
|
Map.entry("0x0027", "fid-heating-mode"), // FID_HEATING_ACTUATOR
|
||||||
|
Map.entry("0x0028", "fid-force-position-blind"), // FID_FORCE_UP_DOWN_SENSOR
|
||||||
|
Map.entry("0x0029", "fid-auto.-heating/cooling-mode"), // FID_HEATING_COOLING_ACTUATOR
|
||||||
|
Map.entry("0x002A", "fid-switchover-heating/cooling"), // FID_HEATING_COOLING_SENSOR
|
||||||
|
Map.entry("0x002B", "fid-device-settings"), // FID_DES_DEVICE_SETTINGS
|
||||||
|
Map.entry("0x002E", "fid-dim-actuator"), // FID_RGB_W_ACTUATOR
|
||||||
|
Map.entry("0x002F", "fid-dim-actuator"), // FID_RGB_ACTUATOR
|
||||||
|
Map.entry("0x0030", "fid-control-element"), // FID_PANEL_SWITCH_SENSOR
|
||||||
|
Map.entry("0x0031", "fid-dimming-sensor"), // FID_PANEL_DIMMING_SENSOR
|
||||||
|
Map.entry("0x0033", "fid-blind-sensor"), // FID_PANEL_BLIND_SENSOR
|
||||||
|
Map.entry("0x0034", "fid-stairwell-light-sensor"), // FID_PANEL_STAIRCASE_LIGHT_SENSOR
|
||||||
|
Map.entry("0x0035", "fid-force-on/off-sensor"), // FID_PANEL_FORCE_ON_OFF_SENSOR
|
||||||
|
Map.entry("0x0036", "fid-force-position-blind"), // FID_PANEL_FORCE_UP_DOWN_SENSOR
|
||||||
|
Map.entry("0x0037", "fid-scene-sensor"), // FID_PANEL_SCENE_SENSOR
|
||||||
|
Map.entry("0x0038", "fid-room-temperature-controller-extension-unit"), // FID_PANEL_ROOM_TEMPERATURE_CONTROLLER_SLAVE
|
||||||
|
Map.entry("0x0039", "fid-fan-coil-sensor"), // FID_PANEL_FAN_COIL_SENSOR
|
||||||
|
Map.entry("0x003A", "fid-rgb-+-warm-white/cold-white-sensor"), // FID_PANEL_RGB_CT_SENSOR
|
||||||
|
Map.entry("0x003B", "fid-rgb-sensor"), // FID_PANEL_RGB_SENSOR
|
||||||
|
Map.entry("0x003C", "fid-warm-white/cold-white-sensor"), // FID_PANEL_CT_SENSOR
|
||||||
|
Map.entry("0x003D", "fid-add.-stage-for-heating-mode"), // FID_ADDITIONAL_HEATING_ACTUATOR
|
||||||
|
Map.entry("0x003E", "fid-radiator-thermostate"), // FID_RADIATOR_ACTUATOR_MASTER
|
||||||
|
Map.entry("0x003F", "fid-room-temperature-controller-extension-unit"), // FID_RADIATOR_ACTUATOR_SLAVE
|
||||||
|
Map.entry("0x0041", "fid-brightness-sensor"), // FID_BRIGHTNESS_SENSOR
|
||||||
|
Map.entry("0x0042", "fid-rain-sensor"), // FID_RAIN_SENSOR
|
||||||
|
Map.entry("0x0043", "fid-temperature-sensor"), // FID_TEMPERATURE_SENSOR
|
||||||
|
Map.entry("0x0044", "fid-wind-sensor"), // FID_WIND_SENSOR
|
||||||
|
Map.entry("0x0045", "fid-trigger"), // FID_TRIGGER
|
||||||
|
Map.entry("0x0047", "fid-heating-mode"), // FID_FCA_2_PIPE_HEATING
|
||||||
|
Map.entry("0x0048", "fid-cooling-mode"), // FID_FCA_2_PIPE_COOLING
|
||||||
|
Map.entry("0x0049", "fid-auto.-heating/cooling-mode"), // FID_FCA_2_PIPE_HEATING_COOLING
|
||||||
|
Map.entry("0x004A", "fid-two-valves-for-heating-and-cooling"), // FID_FCA_4_PIPE_HEATING_AND_COOLING
|
||||||
|
Map.entry("0x004B", "fid-window/door"), // FID_WINDOW_DOOR_ACTUATOR
|
||||||
|
Map.entry("0x004E", "fid-abc"), // FID_INVERTER_INFO
|
||||||
|
Map.entry("0x004F", "fid-abd"), // FID_METER_INFO
|
||||||
|
Map.entry("0x0050", "fid-acd"), // FID_BATTERY_INFO
|
||||||
|
Map.entry("0x0051", "fid-timer-program-switch-sensor"), // FID_PANEL_TIMER_PROGRAM_SWITCH_SENSOR
|
||||||
|
Map.entry("0x0055", "fid-zone"), // FID_DOMUSTECH_ZONE
|
||||||
|
Map.entry("0x0056", "fid-central-heating-actuator"), // FID_CENTRAL_HEATING_ACTUATOR
|
||||||
|
Map.entry("0x0057", "fid-central-cooling-actuator"), // FID_CENTRAL_COOLING_ACTUATOR
|
||||||
|
Map.entry("0x0059", "fid-housekeeping"), // FID_HOUSE_KEEPING
|
||||||
|
Map.entry("0x005A", "fid-media-player"), // FID_MEDIA_PLAYER
|
||||||
|
Map.entry("0x005B", "fid-panel-room-temperature-controller-slave-for-battery-device"), // FID_PANEL_ROOM_TEMPERATURE_CONTROLLER_SLAVE_FOR_BATTERY_DEVICE
|
||||||
|
Map.entry("0x0060", "fid-media-player-sensor"), // FID_PANEL_MEDIA_PLAYER_SENSOR
|
||||||
|
Map.entry("0x0061", "fid-roller-blind-actuator"), // FID_BLIND_ACTUATOR
|
||||||
|
Map.entry("0x0062", "fid-attic-window-actuator"), // FID_ATTIC_WINDOW_ACTUATOR
|
||||||
|
Map.entry("0x0063", "fid-awning-actuator"), // FID_AWNING_ACTUATOR
|
||||||
|
Map.entry("0x0064", "fid-windowdoor-position-sensor"), // FID_WINDOW_DOOR_POSITION_SENSOR
|
||||||
|
Map.entry("0x0065", "fid-window/door-position"), // FID_WINDOW_DOOR_POSITION_ACTUATOR
|
||||||
|
Map.entry("0x0066", "fid-media-playback-control-sensor"), // FID_MEDIA_PLAYBACK_CONTROL_SENSOR
|
||||||
|
Map.entry("0x0067", "fid-media-volume-sensor"), // FID_MEDIA_VOLUME_SENSOR
|
||||||
|
Map.entry("0x0068", "fid-dishwasher"), // FID_DISHWASHER
|
||||||
|
Map.entry("0x0069", "fid-laundry"), // FID_LAUNDRY
|
||||||
|
Map.entry("0x006A", "fid-dryer"), // FID_DRYER
|
||||||
|
Map.entry("0x006B", "fid-oven"), // FID_OVEN
|
||||||
|
Map.entry("0x006C", "fid-fridge"), // FID_FRIDGE
|
||||||
|
Map.entry("0x006D", "fid-freezer"), // FID_FREEZER
|
||||||
|
Map.entry("0x006E", "fid-hood"), // FID_HOOD
|
||||||
|
Map.entry("0x006F", "fid-coffee-machine"), // FID_COFFEE_MACHINE
|
||||||
|
Map.entry("0x0070", "fid-fridge/freezer"), // FID_FRIDGE_FREEZER
|
||||||
|
Map.entry("0x0071", "fid-timer-program-switch-sensor"), // FID_TIMER_PROGRAM_OR_ALERT_SWITCH_SENSOR
|
||||||
|
Map.entry("0x0073", "fid-ceiling-fan-actuator"), // FID_CEILING_FAN_ACTUATOR
|
||||||
|
Map.entry("0x0074", "fid-ceiling-fan-sensor"), // FID_CEILING_FAN_SENSOR
|
||||||
|
Map.entry("0x0075", "fid-room-temperature-controller-with-fan-speed-level"), // FID_SPLIT_UNIT_GATEWAY
|
||||||
|
Map.entry("0x0076", "fid-zone"), // FID_ZONE
|
||||||
|
Map.entry("0x0077", "fid-safety"), // FID_24H_ZONE
|
||||||
|
Map.entry("0x0078", "fid-external-ir-sensor-bx80"), // FID_EXTERNAL_IR_SENSOR_BX80
|
||||||
|
Map.entry("0x0079", "fid-external-ir-sensor-vxi"), // FID_EXTERNAL_IR_SENSOR_VXI
|
||||||
|
Map.entry("0x007A", "fid-external-ir-sensor-mini"), // FID_EXTERNAL_IR_SENSOR_MINI
|
||||||
|
Map.entry("0x007B", "fid-external-ir-sensor-high-altitude"), // FID_EXTERNAL_IR_SENSOR_HIGH_ALTITUDE
|
||||||
|
Map.entry("0x007C", "fid-external-ir-sensor-curtain"), // FID_EXTERNAL_IR_SENSOR_CURTAIN
|
||||||
|
Map.entry("0x007D", "fid-smoke-detector"), // FID_SMOKE_DETECTOR
|
||||||
|
Map.entry("0x007E", "fid-carbon-monoxide-sensor"), // FID_CARBON_MONOXIDE_SENSOR
|
||||||
|
Map.entry("0x007F", "fid-methane-detector"), // FID_METHANE_DETECTOR
|
||||||
|
Map.entry("0x0080", "fid-gas-sensor-lpg"), // FID_GAS_SENSOR_LPG
|
||||||
|
Map.entry("0x0081", "fid-flood-detection"), // FID_FLOOD_DETECTION
|
||||||
|
Map.entry("0x0082", "fid-secure@home-central-unit"), // FID_DOMUS_CENTRAL_UNIT_NEXTGEN
|
||||||
|
Map.entry("0x0083", "fid-thermostat"), // FID_THERMOSTAT
|
||||||
|
Map.entry("0x0084", "fid-secure@home-zone-sensor"), // FID_PANEL_DOMUS_ZONE_SENSOR
|
||||||
|
Map.entry("0x0085", "fid-slave-thermostat"), // FID_THERMOSTAT_SLAVE
|
||||||
|
Map.entry("0x0086", "fid-secure@home-integration-logic"), // FID_DOMUS_SECURE_INTEGRATION
|
||||||
|
Map.entry("0x0087", "fid-add.-stage-for-cooling-mode"), // FID_ADDITIONAL_COOLING_ACTUATOR
|
||||||
|
Map.entry("0x0088", "fid-two-level-heating-actuator"), // FID_TWO_LEVEL_HEATING_ACTUATOR
|
||||||
|
Map.entry("0x0089", "fid-two-level-cooling-actuator"), // FID_TWO_LEVEL_COOLING_ACTUATOR
|
||||||
|
Map.entry("0x008E", "fid-zone"), // FID_GLOBAL_ZONE
|
||||||
|
Map.entry("0x008F", "fid-volume-up"), // FID_VOLUME_UP_SENSOR
|
||||||
|
Map.entry("0x0090", "fid-volume-down"), // FID_VOLUME_DOWN_SENSOR
|
||||||
|
Map.entry("0x0091", "fid-play/pause"), // FID_PLAY_PAUSE_SENSOR
|
||||||
|
Map.entry("0x0092", "fid-next-favorite"), // FID_NEXT_FAVORITE_SENSOR
|
||||||
|
Map.entry("0x0093", "fid-next-song"), // FID_NEXT_SONG_SENSOR
|
||||||
|
Map.entry("0x0094", "fid-previous-song"), // FID_PREVIOUS_SONG_SENSOR
|
||||||
|
Map.entry("0x0095", "fid-home-appliance-sensor"), // FID_HOME_APPLIANCE_SENSOR
|
||||||
|
Map.entry("0x0096", "fid-heat-sensor"), // FID_HEAT_SENSOR
|
||||||
|
Map.entry("0x0097", "fid-zone-switching"), // FID_ZONE_SWITCHING
|
||||||
|
Map.entry("0x0098", "fid-button-function"), // FID_SECURE_AT_HOME_FUNCTION
|
||||||
|
Map.entry("0x0099", "fid-advanced-configuration"), // FID_COMPLEX_CONFIGURATION
|
||||||
|
Map.entry("0x009A", "fid-secure@home-central-unit-basic"), // FID_DOMUS_CENTRAL_UNIT_BASIC
|
||||||
|
Map.entry("0x009B", "fid-repeater"), // FID_DOMUS_REPEATER
|
||||||
|
Map.entry("0x009C", "fid-remote-scene-control"), // FID_DOMUS_SCENE_TRIGGER
|
||||||
|
Map.entry("0x009D", "fid-window-sensor"), // FID_DOMUSWINDOWCONTACT
|
||||||
|
Map.entry("0x009E", "fid-movement-detector"), // FID_DOMUSMOVEMENTDETECTOR
|
||||||
|
Map.entry("0x009F", "fid-external-ir-sensor-curtain"), // FID_DOMUSCURTAINDETECTOR
|
||||||
|
Map.entry("0x00A0", "fid-smoke-detector"), // FID_DOMUSSMOKEDETECTOR
|
||||||
|
Map.entry("0x00A1", "fid-flood-detection"), // FID_DOMUSFLOODDETECTOR
|
||||||
|
Map.entry("0x00A3", "fid-sensor-for-air-conditioning-unit"), // FID_PANEL_SUG_SENSOR
|
||||||
|
Map.entry("0x00A4", "fid-two-point-controller-for-heating-or-cooling"), // FID_TWO_LEVEL_HEATING_COOLING_ACTUATOR
|
||||||
|
Map.entry("0x00A5", "fid-slave-thermostat"), // FID_PANEL_THERMOSTAT_CONTROLLER_SLAVE
|
||||||
|
Map.entry("0x00A6", "fid-wallbox"), // FID_WALLBOX
|
||||||
|
Map.entry("0x00A7", "fid-wallbox"), // FID_PANEL_WALLBOX
|
||||||
|
Map.entry("0x00A8", "fid-door-lock-control"), // FID_DOOR_LOCK_CONTROL
|
||||||
|
Map.entry("0x00AA", "fid-room-temperature-controller-with-fan-speed-level"), // FID_VRV_GATEWAY
|
||||||
|
Map.entry("0x4800", "fid-scene-trigger"), // FID_SCENE_TRIGGER
|
||||||
|
Map.entry("0x4A00", "fid-rule-switch"), // FID_RULE_SWITCH
|
||||||
|
Map.entry("0xE017", "fid-air-quality-sensor-pressure"), // FID_AIRQUALITYSENSOR_PRESSURE
|
||||||
|
Map.entry("0xE018", "fid-air-quality-sensor-co2"), // FID_AIRQUALITYSENSOR_CO2
|
||||||
|
Map.entry("0xE019", "fid-air-quality-sensor-co"), // FID_AIRQUALITYSENSOR_CO
|
||||||
|
Map.entry("0xE01A", "fid-air-quality-sensor-no2"), // FID_AIRQUALITYSENSOR_NO2
|
||||||
|
Map.entry("0xE01B", "fid-air-quality-sensor-o3"), // FID_AIRQUALITYSENSOR_O3
|
||||||
|
Map.entry("0xE01C", "fid-air-quality-sensor-pm10"), // FID_AIRQUALITYSENSOR_PM10
|
||||||
|
Map.entry("0xE01D", "fid-air-quality-sensor-pm25"), // FID_AIRQUALITYSENSOR_PM25
|
||||||
|
Map.entry("0xE01E", "fid-air-quality-sensor-voc"), // FID_AIRQUALITYSENSOR_VOC
|
||||||
|
Map.entry("0xB03F", "fid-air-quality-sensor-humidity"), // FID_AIRQUALITYSENSOR_HUMIDITY
|
||||||
|
Map.entry("0x1090", "fid-movement-detector-flex"), // FID_MOVEMENT_DETECTOR_FLEX
|
||||||
|
Map.entry("0x1810", "fid-dim-actuator-flex") // FID_SWITCH_ACTUATOR_FLEX
|
||||||
|
);
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static String getFunctionIdText(String Key) throws FreeAtHomeGeneralException {
|
||||||
|
String result = MAP_FUNCTION_ID.get(Key);
|
||||||
|
|
||||||
|
if (result != null) {
|
||||||
|
return MAP_FUNCTION_ID.get(Key);
|
||||||
|
} else {
|
||||||
|
throw new FreeAtHomeGeneralException(0,
|
||||||
|
String.format("%s - Key:%s", "FID is not in the translation table", Key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,73 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2024 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.freeathomesystem.internal.util;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link FreeAtHomeGeneralException} is responsible for handling general exceptions in the free@home binding
|
||||||
|
*
|
||||||
|
* @author Andras Uhrin - Initial contribution
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class FreeAtHomeGeneralException extends Exception {
|
||||||
|
private static final long serialVersionUID = -835448863173642860L;
|
||||||
|
private String errorMessage = "Unknown_Exception";
|
||||||
|
private int errorCode = 0;
|
||||||
|
|
||||||
|
public FreeAtHomeGeneralException(int errorCode, String message) {
|
||||||
|
super(message);
|
||||||
|
|
||||||
|
this.errorMessage = message;
|
||||||
|
this.errorCode = errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable String getMessage() {
|
||||||
|
return this.errorMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getErrorCode() {
|
||||||
|
return this.errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "FreeAtHomeHttpCommunicationException [errorMessage=" + errorMessage + ", errorCode=" + errorCode + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(errorCode, errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(@Nullable Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
FreeAtHomeGeneralException other = (FreeAtHomeGeneralException) obj;
|
||||||
|
|
||||||
|
return errorCode == other.errorCode && Objects.equals(errorMessage, other.errorMessage);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,74 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2024 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.freeathomesystem.internal.util;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link FreeAtHomeHttpCommunicationException} is responsible for handling the communication exception to the SysAp
|
||||||
|
* via HTTP link
|
||||||
|
*
|
||||||
|
* @author Andras Uhrin - Initial contribution
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class FreeAtHomeHttpCommunicationException extends Exception {
|
||||||
|
private static final long serialVersionUID = -817364286035448863L;
|
||||||
|
private String errorMessage = "Unknown_Exception";
|
||||||
|
private int errorCode;
|
||||||
|
|
||||||
|
public FreeAtHomeHttpCommunicationException(int errorCode, String message) {
|
||||||
|
super(message);
|
||||||
|
|
||||||
|
this.errorMessage = message;
|
||||||
|
this.errorCode = errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable String getMessage() {
|
||||||
|
return this.errorMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getErrorCode() {
|
||||||
|
return this.errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "FreeAtHomeHttpCommunicationException [errorMessage=" + errorMessage + ", errorCode=" + errorCode + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(errorCode, errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(@Nullable Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
FreeAtHomeHttpCommunicationException other = (FreeAtHomeHttpCommunicationException) obj;
|
||||||
|
|
||||||
|
return errorCode == other.errorCode && Objects.equals(errorMessage, other.errorMessage);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,54 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2024 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.freeathomesystem.internal.util;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link PIdContainerClass} is a helper class for pairing IDs
|
||||||
|
*
|
||||||
|
* @author Andras Uhrin - Initial contribution
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class PIdContainerClass {
|
||||||
|
String valueType;
|
||||||
|
String category;
|
||||||
|
int min;
|
||||||
|
int max;
|
||||||
|
String label;
|
||||||
|
String description;
|
||||||
|
|
||||||
|
PIdContainerClass(String pValueType, String pCategory, String pMin, String pMax, String pLabel,
|
||||||
|
String pDescription) {
|
||||||
|
this.valueType = pValueType;
|
||||||
|
|
||||||
|
this.category = pCategory;
|
||||||
|
|
||||||
|
if (pMax.isEmpty()) {
|
||||||
|
this.min = 0;
|
||||||
|
} else {
|
||||||
|
this.min = Integer.parseInt(pMin);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pMax.isEmpty()) {
|
||||||
|
this.max = 100;
|
||||||
|
} else {
|
||||||
|
this.max = Integer.parseInt(pMax);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.label = pLabel;
|
||||||
|
|
||||||
|
this.description = pDescription;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,829 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2024 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.freeathomesystem.internal.util;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link PidTranslationUtils} supporting the translation from pairing IDs into openHAB types
|
||||||
|
*
|
||||||
|
* @author Andras Uhrin - Initial contribution
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class PidTranslationUtils {
|
||||||
|
public static final String PID_VALUETYPE_UNKNOWN = "unknown";
|
||||||
|
public static final String PID_VALUETYPE_BOOLEAN = "boolean";
|
||||||
|
public static final String PID_VALUETYPE_DECIMAL = "decimal";
|
||||||
|
public static final String PID_VALUETYPE_INTEGER = "integer";
|
||||||
|
public static final String PID_VALUETYPE_STRING = "string";
|
||||||
|
public static final String PID_VALUETYPE_SHUTTERMOVEMENT = "shuttermovement";
|
||||||
|
public static final String PID_VALUETYPE_ENUM = "enum";
|
||||||
|
|
||||||
|
public static final String CATEGORY_UNDEFINED = "-";
|
||||||
|
public static final String CATEGORY_BATTERY = "Battery";
|
||||||
|
public static final String CATEGORY_ALARM = "Alarm";
|
||||||
|
public static final String CATEGORY_HUMIDITY = "Humidity";
|
||||||
|
public static final String CATEGORY_TEMPERATURE = "Temperature";
|
||||||
|
public static final String CATEGORY_MOTION = "Motion";
|
||||||
|
public static final String CATEGORY_PRESSURE = "Pressure";
|
||||||
|
public static final String CATEGORY_SMOKE = "Smoke";
|
||||||
|
public static final String CATEGORY_WATER = "Water";
|
||||||
|
public static final String CATEGORY_WIND = "Wind";
|
||||||
|
public static final String CATEGORY_RAIN = "Rain";
|
||||||
|
public static final String CATEGORY_ENERGY = "Energy";
|
||||||
|
public static final String CATEGORY_BLINDS = "Blinds";
|
||||||
|
public static final String CATEGORY_CONTACT = "Contact";
|
||||||
|
public static final String CATEGORY_SWITCH = "Switch";
|
||||||
|
|
||||||
|
private static final Map<String, PIdContainerClass> MAP_PAIRING_ID = Map.ofEntries(
|
||||||
|
Map.entry("0x0001",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_BOOLEAN, CATEGORY_SWITCH, "0", "1", "pid-switch-on-off",
|
||||||
|
"pid-switch-on-off-text")),
|
||||||
|
Map.entry("0x0002",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_BOOLEAN, CATEGORY_SWITCH, "", "", "pid-timed-start-stop",
|
||||||
|
"pid-timed-start-stop-text")),
|
||||||
|
Map.entry("0x0003",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_BOOLEAN, CATEGORY_SWITCH, "", "", "pid-force-position",
|
||||||
|
"pid-force-position-text")),
|
||||||
|
Map.entry("0x0004",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_BOOLEAN, CATEGORY_SWITCH, "", "", "pid-scene-control",
|
||||||
|
"pid-scene-control-text")),
|
||||||
|
Map.entry("0x0006",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_BOOLEAN, CATEGORY_MOTION, "", "",
|
||||||
|
"pid-movement-under-consideration-of-brightness",
|
||||||
|
"pid-movement-under-consideration-of-brightness-text")),
|
||||||
|
Map.entry("0x0007",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_BOOLEAN, CATEGORY_MOTION, "", "", "pid-presence",
|
||||||
|
"pid-presence-text")),
|
||||||
|
Map.entry("0x0010",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_INTEGER, CATEGORY_UNDEFINED, "", "", "pid-relative-set-value",
|
||||||
|
"pid-relative-set-value-text")),
|
||||||
|
Map.entry("0x0011",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_INTEGER, CATEGORY_UNDEFINED, "", "", "pid-absolute-set-value",
|
||||||
|
"pid-absolute-set-value-text")),
|
||||||
|
Map.entry("0x0012",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_INTEGER, CATEGORY_UNDEFINED, "", "", "pid-night",
|
||||||
|
"pid-night-text")),
|
||||||
|
Map.entry("0x0013",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_INTEGER, CATEGORY_UNDEFINED, "", "", "pid-invalid-string-id",
|
||||||
|
"pid-invalid-string-id-text")),
|
||||||
|
Map.entry("0x0015",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-rgb-color",
|
||||||
|
"pid-rgb-color-text")),
|
||||||
|
Map.entry("0x0016",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-color-temperature",
|
||||||
|
"pid-color-temperature-text")),
|
||||||
|
Map.entry("0x0017",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-hsv",
|
||||||
|
"pid-hsv-text")),
|
||||||
|
Map.entry("0x0018",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-hue",
|
||||||
|
"pid-hue-text")),
|
||||||
|
Map.entry("0x0019",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-saturation",
|
||||||
|
"pid-saturation-text")),
|
||||||
|
Map.entry("0x0020",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_SHUTTERMOVEMENT, CATEGORY_BLINDS, "", "", "pid-move-up-down",
|
||||||
|
"pid-move-up-down-text")),
|
||||||
|
Map.entry("0x0021",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_SHUTTERMOVEMENT, CATEGORY_BLINDS, "", "", "pid-adjust-up-down",
|
||||||
|
"pid-adjust-up-down-text")),
|
||||||
|
Map.entry("0x0023",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_INTEGER, CATEGORY_BLINDS, "0", "100",
|
||||||
|
"pid-set-absolute-position-blinds", "pid-set-absolute-position-blinds-text")),
|
||||||
|
Map.entry("0x0024",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_INTEGER, CATEGORY_BLINDS, "0", "100",
|
||||||
|
"pid-set-absolute-position-slats", "pid-set-absolute-position-slats-text")),
|
||||||
|
Map.entry("0x0025",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_BOOLEAN, CATEGORY_WIND, "", "", "pid-wind-alarm",
|
||||||
|
"pid-wind-alarm-text")),
|
||||||
|
Map.entry("0x0026",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_BOOLEAN, CATEGORY_TEMPERATURE, "", "", "pid-frost-alarm",
|
||||||
|
"pid-frost-alarm-text")),
|
||||||
|
Map.entry("0x0027",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_BOOLEAN, CATEGORY_RAIN, "", "", "pid-rain-alarm",
|
||||||
|
"pid-rain-alarm-text")),
|
||||||
|
Map.entry("0x0028",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_BOOLEAN, CATEGORY_UNDEFINED, "", "", "pid-force-position-blind",
|
||||||
|
"pid-force-position-blind-text")),
|
||||||
|
Map.entry("0x0029",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_INTEGER, CATEGORY_UNDEFINED, "", "", "pid-window-door-position",
|
||||||
|
"pid-window-door-position-text")),
|
||||||
|
Map.entry("0x0030",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_INTEGER, CATEGORY_TEMPERATURE, "", "",
|
||||||
|
"pid-actuating-value-heating", "pid-actuating-value-heating-text")),
|
||||||
|
Map.entry("0x0031",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_INTEGER, CATEGORY_UNDEFINED, "", "", "pid-fan-level-heating",
|
||||||
|
"pid-fan-level-heating-text")),
|
||||||
|
Map.entry("0x0032",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_INTEGER, CATEGORY_TEMPERATURE, "", "",
|
||||||
|
"pid-actuating-value-cooling", "pid-actuating-value-cooling-text")),
|
||||||
|
Map.entry("0x0033",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_DECIMAL, CATEGORY_TEMPERATURE, "7", "30",
|
||||||
|
"pid-set-value-temperature", "pid-set-value-temperature-text")),
|
||||||
|
Map.entry("0x0034",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_DECIMAL, CATEGORY_TEMPERATURE, "7", "30",
|
||||||
|
"pid-relative-set-point-temperature", "pid-relative-set-point-temperature-text")),
|
||||||
|
Map.entry("0x0035",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_INTEGER, CATEGORY_UNDEFINED, "", "", "pid-window-door",
|
||||||
|
"pid-window-door-text")),
|
||||||
|
Map.entry("0x0036",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_INTEGER, CATEGORY_TEMPERATURE, "", "", "pid-status-indication",
|
||||||
|
"pid-status-indication-text")),
|
||||||
|
Map.entry("0x0037",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_BOOLEAN, CATEGORY_SWITCH, "", "",
|
||||||
|
"pid-fan-manual-heating-on-off", "pid-fan-manual-heating-on-off-text")),
|
||||||
|
Map.entry("0x0038",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_BOOLEAN, CATEGORY_SWITCH, "", "", "pid-controller-on-off",
|
||||||
|
"pid-controller-on-off-text")),
|
||||||
|
Map.entry("0x0039",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_DECIMAL, CATEGORY_TEMPERATURE, "7", "30",
|
||||||
|
"pid-relative-set-point-request", "pid-relative-set-point-request-text")),
|
||||||
|
Map.entry("0x003A",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_BOOLEAN, CATEGORY_SWITCH, "", "", "pid-eco-mode-on-off-request",
|
||||||
|
"pid-eco-mode-on-off-request-text")),
|
||||||
|
Map.entry("0x003B",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_DECIMAL, CATEGORY_TEMPERATURE, "7", "30",
|
||||||
|
"pid-comfort-temperature", "pid-comfort-temperature-text")),
|
||||||
|
Map.entry("0x0040",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_INTEGER, CATEGORY_UNDEFINED, "", "", "pid-fan-level-request",
|
||||||
|
"pid-fan-level-request-text")),
|
||||||
|
Map.entry("0x0041",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_BOOLEAN, CATEGORY_SWITCH, "", "",
|
||||||
|
"pid-fan-manual-on-off-request", "pid-fan-manual-on-off-request-text")),
|
||||||
|
Map.entry("0x0042",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_BOOLEAN, CATEGORY_SWITCH, "", "",
|
||||||
|
"pid-controller-on-off-request", "pid-controller-on-off-request-text")),
|
||||||
|
Map.entry("0x0044",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_BOOLEAN, CATEGORY_SWITCH, "", "", "pid-eco-mode-on-off-request",
|
||||||
|
"pid-eco-mode-on-off-request-text")),
|
||||||
|
Map.entry("0x0100",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_BOOLEAN, CATEGORY_SWITCH, "", "", "pid-info-on-off",
|
||||||
|
"pid-info-on-off-text")),
|
||||||
|
Map.entry("0x0101",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_BOOLEAN, CATEGORY_UNDEFINED, "", "", "pid-force-position-info",
|
||||||
|
"pid-force-position-info-text")),
|
||||||
|
Map.entry("0x0105",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_BOOLEAN, CATEGORY_UNDEFINED, "", "", "pid-sysap-infoonoff",
|
||||||
|
"pid-sysap-infoonoff-text")),
|
||||||
|
Map.entry("0x0106",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_INTEGER, CATEGORY_UNDEFINED, "", "", "pid-sysap-infoforce",
|
||||||
|
"pid-sysap-infoforce-text")),
|
||||||
|
Map.entry("0x0110",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_INTEGER, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-info-actual-dimming-value", "pid-info-actual-dimming-value-text")),
|
||||||
|
Map.entry("0x0111",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_INTEGER, CATEGORY_UNDEFINED, "", "", "pid-info-error",
|
||||||
|
"pid-info-error-text")),
|
||||||
|
Map.entry("0x0115",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_INTEGER, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-sysap-infocurrentdimmingvalue", "pid-sysap-infocurrentdimmingvalue-text")),
|
||||||
|
Map.entry("0x0116",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_INTEGER, CATEGORY_UNDEFINED, "", "", "pid-sysap-infoerror",
|
||||||
|
"pid-sysap-infoerror-text")),
|
||||||
|
Map.entry("0x0118",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-info-color-temperature", "pid-info-color-temperature-text")),
|
||||||
|
Map.entry("0x011A",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-sysap-info-color-temperature", "pid-sysap-info-color-temperature-text")),
|
||||||
|
Map.entry("0x011B",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-info-hsv",
|
||||||
|
"pid-info-hsv-text")),
|
||||||
|
Map.entry("0x011C",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-sysap-info-hsv",
|
||||||
|
"pid-sysap-info-hsv-text")),
|
||||||
|
Map.entry("0x011D",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-info-color-mode",
|
||||||
|
"pid-info-color-mode-text")),
|
||||||
|
Map.entry("0x011E",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-sysap-info-color-mode", "pid-sysap-info-color-mode-text")),
|
||||||
|
Map.entry("0x0120",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_SHUTTERMOVEMENT, CATEGORY_BLINDS, "", "",
|
||||||
|
"pid-info-move-up-down", "pid-info-move-up-down-text")),
|
||||||
|
Map.entry("0x0121",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_INTEGER, CATEGORY_BLINDS, "", "",
|
||||||
|
"pid-current-absolute-position-blinds-percentage",
|
||||||
|
"pid-current-absolute-position-blinds-percentage-text")),
|
||||||
|
Map.entry("0x0122",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-current-absolute-position-slats-percentage",
|
||||||
|
"pid-current-absolute-position-slats-percentage-text")),
|
||||||
|
Map.entry("0x0125",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-sysap-infomoveupdown",
|
||||||
|
"pid-sysap-infomoveupdown-text")),
|
||||||
|
Map.entry("0x0126",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-sysap-infocurrentabsoluteblindspercentage",
|
||||||
|
"pid-sysap-infocurrentabsoluteblindspercentage-text")),
|
||||||
|
Map.entry("0x0127",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-sysap-infocurrentabsoluteslatspercentage",
|
||||||
|
"pid-sysap-infocurrentabsoluteslatspercentage-text")),
|
||||||
|
Map.entry("0x0130",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_DECIMAL, CATEGORY_TEMPERATURE, "7", "30",
|
||||||
|
"pid-measured-temperature", "pid-measured-temperature-text")),
|
||||||
|
Map.entry("0x0131",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-info-value-heating",
|
||||||
|
"pid-info-value-heating-text")),
|
||||||
|
Map.entry("0x0132",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_INTEGER, CATEGORY_TEMPERATURE, "", "", "pid-info-value-cooling",
|
||||||
|
"pid-info-value-cooling-text")),
|
||||||
|
Map.entry("0x0135",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_INTEGER, CATEGORY_TEMPERATURE, "", "",
|
||||||
|
"pid-switchover-heating-cooling", "pid-switchover-heating-cooling-text")),
|
||||||
|
Map.entry("0x0136",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-actuating-fan-stage-heating", "pid-actuating-fan-stage-heating-text")),
|
||||||
|
Map.entry("0x0140",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_DECIMAL, CATEGORY_TEMPERATURE, "7", "30",
|
||||||
|
"pid-absolute-setpoint-temperature", "pid-absolute-setpoint-temperature-text")),
|
||||||
|
Map.entry("0x0141",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-additional-heating-value-info", "pid-additional-heating-value-info-text")),
|
||||||
|
Map.entry("0x0142",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_INTEGER, CATEGORY_TEMPERATURE, "", "",
|
||||||
|
"pid-additional-cooling-value-info", "pid-additional-cooling-value-info-text")),
|
||||||
|
Map.entry("0x0143",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-control-value-additional-heating", "pid-control-value-additional-heating-text")),
|
||||||
|
Map.entry("0x0144",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_INTEGER, CATEGORY_TEMPERATURE, "", "",
|
||||||
|
"pid-control-value-additional-cooling", "pid-control-value-additional-cooling-text")),
|
||||||
|
Map.entry("0x0145",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-info-actuating-fan-stage-heating", "pid-info-actuating-fan-stage-heating-text")),
|
||||||
|
Map.entry("0x0146",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-info-actuating-fan-manual-on-off-heating",
|
||||||
|
"pid-info-actuating-fan-manual-on-off-heating-text")),
|
||||||
|
Map.entry("0x0147",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_INTEGER, CATEGORY_TEMPERATURE, "", "",
|
||||||
|
"pid-actuating-fan-stage-cooling", "pid-actuating-fan-stage-cooling-text")),
|
||||||
|
Map.entry("0x0149",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_INTEGER, CATEGORY_TEMPERATURE, "", "",
|
||||||
|
"pid-info-fan-stage-cooling", "pid-info-fan-stage-cooling-text")),
|
||||||
|
Map.entry("0x014A",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_BOOLEAN, CATEGORY_TEMPERATURE, "", "",
|
||||||
|
"pid-info-fan-manual-on-off-cooling", "pid-info-fan-manual-on-off-cooling-text")),
|
||||||
|
Map.entry("0x014B",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_INTEGER, CATEGORY_TEMPERATURE, "", "", "pid-heating-active",
|
||||||
|
"pid-heating-active-text")),
|
||||||
|
Map.entry("0x014C",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_INTEGER, CATEGORY_TEMPERATURE, "", "", "pid-cooling-active",
|
||||||
|
"pid-cooling-active-text")),
|
||||||
|
Map.entry("0x014D",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_INTEGER, CATEGORY_TEMPERATURE, "", "", "pid-heating-demand",
|
||||||
|
"pid-heating-demand-text")),
|
||||||
|
Map.entry("0x014E",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_INTEGER, CATEGORY_TEMPERATURE, "", "", "pid-cooling-demand",
|
||||||
|
"pid-cooling-demand-text")),
|
||||||
|
Map.entry("0x014F",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_INTEGER, CATEGORY_TEMPERATURE, "", "",
|
||||||
|
"pid-heating-demand-feedback-signal", "pid-heating-demand-feedback-signal-text")),
|
||||||
|
Map.entry("0x0150",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_INTEGER, CATEGORY_TEMPERATURE, "", "",
|
||||||
|
"pid-cooling-demand-feedback-signal", "pid-cooling-demand-feedback-signal-text")),
|
||||||
|
Map.entry("0x0151",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_INTEGER, CATEGORY_HUMIDITY, "", "", "pid-humidity",
|
||||||
|
"pid-humidity-text")),
|
||||||
|
Map.entry("0x0152",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-aux-on-off-request",
|
||||||
|
"pid-aux-on-off-request-text")),
|
||||||
|
Map.entry("0x0153",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-aux-on-off-response",
|
||||||
|
"pid-aux-on-off-response-text")),
|
||||||
|
Map.entry("0x0154",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_BOOLEAN, CATEGORY_SWITCH, "", "", "pid-heating-on-off-request",
|
||||||
|
"pid-heating-on-off-request-text")),
|
||||||
|
Map.entry("0x0155",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_BOOLEAN, CATEGORY_SWITCH, "", "", "pid-cooling-on-off-request",
|
||||||
|
"pid-cooling-on-off-request-text")),
|
||||||
|
Map.entry("0x0156",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-operation-mode",
|
||||||
|
"pid-operation-mode-text")),
|
||||||
|
Map.entry("0x0157",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-swing-h-v",
|
||||||
|
"pid-swing-h-v-text")),
|
||||||
|
Map.entry("0x0158",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-supported-features",
|
||||||
|
"pid-supported-features-text")),
|
||||||
|
Map.entry("0x0159",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-extended-status-indication", "pid-extended-status-indication-text")),
|
||||||
|
Map.entry("0x015A",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-extended-status-indication", "pid-extended-status-indication-text")),
|
||||||
|
Map.entry("0x015B",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-aux-heating-on-off-request", "pid-aux-heating-on-off-request-text")),
|
||||||
|
Map.entry("0x015C",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-emergency-heating-on-off-request", "pid-emergency-heating-on-off-request-text")),
|
||||||
|
Map.entry("0x0160",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-relative-fan-speed-control", "pid-relative-fan-speed-control-text")),
|
||||||
|
Map.entry("0x0161",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-absolute-fan-speed-control", "pid-absolute-fan-speed-control-text")),
|
||||||
|
Map.entry("0x0162",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-info-absolute-fan-speed", "pid-info-absolute-fan-speed-text")),
|
||||||
|
Map.entry("0x0163",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-sysap-infoactualfanspeed", "pid-sysap-infoactualfanspeed-text")),
|
||||||
|
Map.entry("0x01A0",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-notification-flags",
|
||||||
|
"pid-notification-flags-text")),
|
||||||
|
Map.entry("0x0280",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-power-rc",
|
||||||
|
"pid-power-rc-text")),
|
||||||
|
Map.entry("0x0281",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-power-rh",
|
||||||
|
"pid-power-rh-text")),
|
||||||
|
Map.entry("0x0282",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-proximity-status",
|
||||||
|
"pid-proximity-status-text")),
|
||||||
|
Map.entry("0x0290",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-brightness-sensor",
|
||||||
|
"pid-brightness-sensor-text")),
|
||||||
|
Map.entry("0x0291",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-last-touch",
|
||||||
|
"pid-last-touch-text")),
|
||||||
|
Map.entry("0x0292",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-led-backlighting-night-mode", "pid-led-backlighting-night-mode-text")),
|
||||||
|
Map.entry("0x02C0",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-locator-beep",
|
||||||
|
"pid-locator-beep-text")),
|
||||||
|
Map.entry("0x02C1",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-switch-test-alarm",
|
||||||
|
"pid-switch-test-alarm-text")),
|
||||||
|
Map.entry("0x02C3",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-fire-alarm-active",
|
||||||
|
"pid-fire-alarm-active-text")),
|
||||||
|
Map.entry("0x0400",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_DECIMAL, CATEGORY_TEMPERATURE, "", "",
|
||||||
|
"pid-outside-temperature", "pid-outside-temperature-text")),
|
||||||
|
Map.entry("0x0401",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_DECIMAL, CATEGORY_WIND, "", "", "pid-wind-force",
|
||||||
|
"pid-wind-force-text")),
|
||||||
|
Map.entry("0x0402",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_BOOLEAN, CATEGORY_UNDEFINED, "", "", "pid-brightness-alarm",
|
||||||
|
"pid-brightness-alarm-text")),
|
||||||
|
Map.entry("0x0403",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_DECIMAL, CATEGORY_UNDEFINED, "", "", "pid-lux-value",
|
||||||
|
"pid-lux-value-text")),
|
||||||
|
Map.entry("0x0404",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_DECIMAL, CATEGORY_WIND, "", "", "pid-wind-speed",
|
||||||
|
"pid-wind-speed-text")),
|
||||||
|
Map.entry("0x0405",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_INTEGER, CATEGORY_RAIN, "", "", "pid-rain-detection",
|
||||||
|
"pid-rain-detection-text")),
|
||||||
|
Map.entry("0x0406",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_INTEGER, CATEGORY_RAIN, "", "", "pid-rain-sensor-frequency",
|
||||||
|
"pid-rain-sensor-frequency-text")),
|
||||||
|
Map.entry("0x0440",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-play",
|
||||||
|
"pid-play-text")),
|
||||||
|
Map.entry("0x0441",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-pause",
|
||||||
|
"pid-pause-text")),
|
||||||
|
Map.entry("0x0442",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-next",
|
||||||
|
"pid-next-text")),
|
||||||
|
Map.entry("0x0443",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-previous",
|
||||||
|
"pid-previous-text")),
|
||||||
|
Map.entry("0x0444",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-play-mode",
|
||||||
|
"pid-play-mode-text")),
|
||||||
|
Map.entry("0x0445",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-mute",
|
||||||
|
"pid-mute-text")),
|
||||||
|
Map.entry("0x0446",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-relative-volume-control", "pid-relative-volume-control-text")),
|
||||||
|
Map.entry("0x0447",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-absolute-volume-control", "pid-absolute-volume-control-text")),
|
||||||
|
Map.entry("0x0448",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-group-membership",
|
||||||
|
"pid-group-membership-text")),
|
||||||
|
Map.entry("0x0449",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-play-favorite",
|
||||||
|
"pid-play-favorite-text")),
|
||||||
|
Map.entry("0x044A",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-play-next-favorite",
|
||||||
|
"pid-play-next-favorite-text")),
|
||||||
|
Map.entry("0x0460",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-playback-status",
|
||||||
|
"pid-playback-status-text")),
|
||||||
|
Map.entry("0x0461",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-current-item-metadata-info", "pid-current-item-metadata-info-text")),
|
||||||
|
Map.entry("0x0462",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-info-mute",
|
||||||
|
"pid-info-mute-text")),
|
||||||
|
Map.entry("0x0463",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-info-actual-volume",
|
||||||
|
"pid-info-actual-volume-text")),
|
||||||
|
Map.entry("0x0464",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-allowed-playback-actions", "pid-allowed-playback-actions-text")),
|
||||||
|
Map.entry("0x0465",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-info-group-membership", "pid-info-group-membership-text")),
|
||||||
|
Map.entry("0x0466",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-info-playing-favorite", "pid-info-playing-favorite-text")),
|
||||||
|
Map.entry("0x0467",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-absolute-group-volume-control", "pid-absolute-group-volume-control-text")),
|
||||||
|
Map.entry("0x0468",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-info-absolute-group-volume", "pid-info-absolute-group-volume-text")),
|
||||||
|
Map.entry("0x0469",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-media-source",
|
||||||
|
"pid-media-source-text")),
|
||||||
|
Map.entry("0x04A0",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-solar-power-production", "pid-solar-power-production-text")),
|
||||||
|
Map.entry("0x04A1",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-inverter-output-power", "pid-inverter-output-power-text")),
|
||||||
|
Map.entry("0x04A2",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-solar-energy-(today)",
|
||||||
|
"pid-solar-energy-(today)-text")),
|
||||||
|
Map.entry("0x04A3",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-injected-energy-(today)", "pid-injected-energy-(today)-text")),
|
||||||
|
Map.entry("0x04A4",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-purchased-energy-(today)", "pid-purchased-energy-(today)-text")),
|
||||||
|
Map.entry("0x04A5",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-inverter-alarm",
|
||||||
|
"pid-inverter-alarm-text")),
|
||||||
|
Map.entry("0x04A6",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-self-consumption",
|
||||||
|
"pid-self-consumption-text")),
|
||||||
|
Map.entry("0x04A7",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-self-sufficiency",
|
||||||
|
"pid-self-sufficiency-text")),
|
||||||
|
Map.entry("0x04A8",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-home-power-consumption", "pid-home-power-consumption-text")),
|
||||||
|
Map.entry("0x04A9",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-power-to-grid",
|
||||||
|
"pid-power-to-grid-text")),
|
||||||
|
Map.entry("0x04AA",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-consumed-energy-(today)", "pid-consumed-energy-(today)-text")),
|
||||||
|
Map.entry("0x04AB",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-meter-alarm",
|
||||||
|
"pid-meter-alarm-text")),
|
||||||
|
Map.entry("0x04AC",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-battery-level",
|
||||||
|
"pid-battery-level-text")),
|
||||||
|
Map.entry("0x04AD",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-battery-power",
|
||||||
|
"pid-battery-power-text")),
|
||||||
|
Map.entry("0x04B0",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-boost",
|
||||||
|
"pid-boost-text")),
|
||||||
|
Map.entry("0x04B1",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-stop-charging-reuqest", "pid-stop-charging-reuqest-text")),
|
||||||
|
Map.entry("0x04B2",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-enable-charging-reuqest", "pid-enable-charging-reuqest-text")),
|
||||||
|
Map.entry("0x04B3",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-info-boost",
|
||||||
|
"pid-info-boost-text")),
|
||||||
|
Map.entry("0x04B4",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-info-wallbox-status",
|
||||||
|
"pid-info-wallbox-status-text")),
|
||||||
|
Map.entry("0x04B5",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-info-charging",
|
||||||
|
"pid-info-charging-text")),
|
||||||
|
Map.entry("0x04B6",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-info-charging-enabled", "pid-info-charging-enabled-text")),
|
||||||
|
Map.entry("0x04B7",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-info-installed-power",
|
||||||
|
"pid-info-installed-power-text")),
|
||||||
|
Map.entry("0x04B8",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-info-transmitted-energy", "pid-info-transmitted-energy-text")),
|
||||||
|
Map.entry("0x04B9",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-info-car-range",
|
||||||
|
"pid-info-car-range-text")),
|
||||||
|
Map.entry("0x04BA",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-info-charging-duration", "pid-info-charging-duration-text")),
|
||||||
|
Map.entry("0x04BB",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-info-current-limit",
|
||||||
|
"pid-info-current-limit-text")),
|
||||||
|
Map.entry("0x04BC",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-info-current-limit-for-group", "pid-info-current-limit-for-group-text")),
|
||||||
|
Map.entry("0x04BD",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-album-cover-url",
|
||||||
|
"pid-album-cover-url-text")),
|
||||||
|
Map.entry("0x0501",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-secure@home-central-unit", "pid-secure@home-central-unit-text")),
|
||||||
|
Map.entry("0x0502",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-domusdisarmcounter",
|
||||||
|
"pid-domusdisarmcounter-text")),
|
||||||
|
Map.entry("0x0504",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-intrusion-alarm",
|
||||||
|
"pid-intrusion-alarm-text")),
|
||||||
|
Map.entry("0x0505",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-safety-alarm",
|
||||||
|
"pid-safety-alarm-text")),
|
||||||
|
Map.entry("0x0507",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-infoconfigurationstatus", "pid-infoconfigurationstatus-text")),
|
||||||
|
Map.entry("0x0508",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-enable-configuration",
|
||||||
|
"pid-enable-configuration-text")),
|
||||||
|
Map.entry("0x0509",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-disarming-led",
|
||||||
|
"pid-disarming-led-text")),
|
||||||
|
Map.entry("0x050A",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-aes-key",
|
||||||
|
"pid-aes-key-text")),
|
||||||
|
Map.entry("0x050B",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-zone-status",
|
||||||
|
"pid-zone-status-text")),
|
||||||
|
Map.entry("0x050E",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-time",
|
||||||
|
"pid-time-text")),
|
||||||
|
Map.entry("0x0600",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-start-stop",
|
||||||
|
"pid-start-stop-text")),
|
||||||
|
Map.entry("0x0601",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-pause-resume",
|
||||||
|
"pid-pause-resume-text")),
|
||||||
|
Map.entry("0x0602",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-select-program",
|
||||||
|
"pid-select-program-text")),
|
||||||
|
Map.entry("0x0603",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-delayed-start-time",
|
||||||
|
"pid-delayed-start-time-text")),
|
||||||
|
Map.entry("0x0604",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-info-status",
|
||||||
|
"pid-info-status-text")),
|
||||||
|
Map.entry("0x0605",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-info-remote-start-enabled", "pid-info-remote-start-enabled-text")),
|
||||||
|
Map.entry("0x0606",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-info-program",
|
||||||
|
"pid-info-program-text")),
|
||||||
|
Map.entry("0x0607",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-info-finish-time",
|
||||||
|
"pid-info-finish-time-text")),
|
||||||
|
Map.entry("0x0608",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-info-delayed-start",
|
||||||
|
"pid-info-delayed-start-text")),
|
||||||
|
Map.entry("0x0609",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-info-door",
|
||||||
|
"pid-info-door-text")),
|
||||||
|
Map.entry("0x060A",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-info-door-alarm",
|
||||||
|
"pid-info-door-alarm-text")),
|
||||||
|
Map.entry("0x060B",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-switch-supercool",
|
||||||
|
"pid-switch-supercool-text")),
|
||||||
|
Map.entry("0x060C",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-switch-superfreeze",
|
||||||
|
"pid-switch-superfreeze-text")),
|
||||||
|
Map.entry("0x060D",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-info-switch-supercool", "pid-info-switch-supercool-text")),
|
||||||
|
Map.entry("0x060E",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-info-switch-superfreeze", "pid-info-switch-superfreeze-text")),
|
||||||
|
Map.entry("0x060F",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-measured-temperature",
|
||||||
|
"pid-measured-temperature-text")),
|
||||||
|
Map.entry("0x0610",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-measured-temperature",
|
||||||
|
"pid-measured-temperature-text")),
|
||||||
|
Map.entry("0x0611",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-set-value-temperature", "pid-set-value-temperature-text")),
|
||||||
|
Map.entry("0x0612",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-set-value-temperature", "pid-set-value-temperature-text")),
|
||||||
|
Map.entry("0x0613",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-change-operation",
|
||||||
|
"pid-change-operation-text")),
|
||||||
|
Map.entry("0x0614",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-detailed-status-info",
|
||||||
|
"pid-detailed-status-info-text")),
|
||||||
|
Map.entry("0x0615",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-info-remaining-time",
|
||||||
|
"pid-info-remaining-time-text")),
|
||||||
|
Map.entry("0x0616",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-time-of-last-status-change", "pid-time-of-last-status-change-text")),
|
||||||
|
Map.entry("0x0618",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-lock-unlock-door-command", "pid-lock-unlock-door-command-text")),
|
||||||
|
Map.entry("0x0619",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-info-locked-unlocked",
|
||||||
|
"pid-info-locked-unlocked-text")),
|
||||||
|
Map.entry("0xF001",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-time",
|
||||||
|
"pid-time-text")),
|
||||||
|
Map.entry("0xF002",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-date",
|
||||||
|
"pid-date-text")),
|
||||||
|
Map.entry("0xF003",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-notification",
|
||||||
|
"pid-notification-text")),
|
||||||
|
Map.entry("0xF101",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_BOOLEAN, CATEGORY_SWITCH, "", "", "pid-switch-entity-on-off",
|
||||||
|
"pid-switch-entity-on-off-text")),
|
||||||
|
Map.entry("0xF102",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_BOOLEAN, CATEGORY_SWITCH, "", "",
|
||||||
|
"pid-info-switch-entity-on-off", "pid-info-switch-entity-on-off-text")),
|
||||||
|
Map.entry("0xF104",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-consistency-tag",
|
||||||
|
"pid-consistency-tag-text")),
|
||||||
|
Map.entry("0xF105",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-battery-status",
|
||||||
|
"pid-battery-status-text")),
|
||||||
|
Map.entry("0xF106",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-stay-awake",
|
||||||
|
"pid-stay-awake-text")),
|
||||||
|
Map.entry("0xF107",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-proxy-switch",
|
||||||
|
"pid-proxy-switch-text")),
|
||||||
|
Map.entry("0xF108",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-proxy1",
|
||||||
|
"pid-proxy1-text")),
|
||||||
|
Map.entry("0xF109",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-proxy2",
|
||||||
|
"pid-proxy2-text")),
|
||||||
|
Map.entry("0xF10A",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-proxy4",
|
||||||
|
"pid-proxy4-text")),
|
||||||
|
Map.entry("0xF10B",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-cyclic-sleep-time",
|
||||||
|
"pid-cyclic-sleep-time-text")),
|
||||||
|
Map.entry("0xF10C",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-presence",
|
||||||
|
"pid-presence-text")),
|
||||||
|
Map.entry("0xF10D",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-measured-temperature-1", "pid-measured-temperature-1-text")),
|
||||||
|
Map.entry("0xF10E",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-standby-statistics",
|
||||||
|
"pid-standby-statistics-text")),
|
||||||
|
Map.entry("0xF10F",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-heartbeat-delay",
|
||||||
|
"pid-heartbeat-delay-text")),
|
||||||
|
Map.entry("0xF110",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "", "pid-info-heartbeat-delay",
|
||||||
|
"pid-info-heartbeat-delay-text")),
|
||||||
|
Map.entry("0xFF01",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-measured-temperature-1", "pid-measured-temperature-1-text")),
|
||||||
|
Map.entry("0xFF02",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-measured-temperature-2", "pid-measured-temperature-2-text")),
|
||||||
|
Map.entry("0xFF03",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-measured-temperature-3", "pid-measured-temperature-3-text")),
|
||||||
|
Map.entry("0xFF04",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_UNKNOWN, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-measured-temperature-4", "pid-measured-temperature-4-text")),
|
||||||
|
Map.entry("0x061A",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_DECIMAL, CATEGORY_PRESSURE, "", "",
|
||||||
|
"pid-air-quality-pressure-value", "pid-air-quality-pressure-value-text")),
|
||||||
|
Map.entry("0x061B",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_INTEGER, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-air-quality-co2-value", "pid-air-quality-co2-value-text")),
|
||||||
|
Map.entry("0x061C",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_INTEGER, CATEGORY_UNDEFINED, "", "", "pid-air-quality-co-value",
|
||||||
|
"pid-air-quality-co-value-text")),
|
||||||
|
Map.entry("0x061D",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_INTEGER, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-air-quality-no2-value", "pid-air-quality-no2-value-text")),
|
||||||
|
Map.entry("0x061E",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_INTEGER, CATEGORY_UNDEFINED, "", "", "pid-air-quality-o3-value",
|
||||||
|
"pid-air-quality-o3-value-text")),
|
||||||
|
Map.entry("0x061F",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_INTEGER, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-air-quality-pm10-value", "pid-air-quality-pm10-value-text")),
|
||||||
|
Map.entry("0x0620",
|
||||||
|
new PIdContainerClass(PID_VALUETYPE_INTEGER, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-air-quality-pm25-value", "pid-air-quality-pm25-value-text")),
|
||||||
|
Map.entry("0x0621", new PIdContainerClass(PID_VALUETYPE_INTEGER, CATEGORY_UNDEFINED, "", "",
|
||||||
|
"pid-air-quality-voc-value", "pid-air-quality-voc-value-text")));
|
||||||
|
|
||||||
|
public static String getShortTextForPairingId(String Key) throws FreeAtHomeGeneralException {
|
||||||
|
PIdContainerClass desc = MAP_PAIRING_ID.get(Key);
|
||||||
|
|
||||||
|
if (desc == null) {
|
||||||
|
throw new FreeAtHomeGeneralException(0,
|
||||||
|
String.format("%s - Key:%s", "PID is not in the translation table", Key));
|
||||||
|
}
|
||||||
|
|
||||||
|
return desc.label;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getDescriptionTextForPairingId(String Key) throws FreeAtHomeGeneralException {
|
||||||
|
PIdContainerClass desc = MAP_PAIRING_ID.get(Key);
|
||||||
|
|
||||||
|
if (desc == null) {
|
||||||
|
throw new FreeAtHomeGeneralException(0,
|
||||||
|
String.format("%s - Key:%s", "PID is not in the translation table", Key));
|
||||||
|
}
|
||||||
|
|
||||||
|
return desc.description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getValueTypeForPairingId(String Key) throws FreeAtHomeGeneralException {
|
||||||
|
PIdContainerClass desc = MAP_PAIRING_ID.get(Key);
|
||||||
|
|
||||||
|
if (desc == null) {
|
||||||
|
throw new FreeAtHomeGeneralException(0,
|
||||||
|
String.format("%s - Key:%s", "PID is not in the translation table", Key));
|
||||||
|
}
|
||||||
|
|
||||||
|
return desc.valueType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getItemTypeForPairingId(String Key) throws FreeAtHomeGeneralException {
|
||||||
|
PIdContainerClass desc = MAP_PAIRING_ID.get(Key);
|
||||||
|
|
||||||
|
if (desc == null) {
|
||||||
|
throw new FreeAtHomeGeneralException(0,
|
||||||
|
String.format("%s - Key:%s", "PID is not in the translation table", Key));
|
||||||
|
}
|
||||||
|
|
||||||
|
return desc.category;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getCategoryForPairingId(String Key) throws FreeAtHomeGeneralException {
|
||||||
|
PIdContainerClass desc = MAP_PAIRING_ID.get(Key);
|
||||||
|
|
||||||
|
if (desc == null) {
|
||||||
|
throw new FreeAtHomeGeneralException(0,
|
||||||
|
String.format("%s - Key:%s", "PID is not in the translation table", Key));
|
||||||
|
}
|
||||||
|
|
||||||
|
return desc.category;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getPatternForPairingId(String Key) throws FreeAtHomeGeneralException {
|
||||||
|
PIdContainerClass desc = MAP_PAIRING_ID.get(Key);
|
||||||
|
|
||||||
|
if (desc == null) {
|
||||||
|
throw new FreeAtHomeGeneralException(0,
|
||||||
|
String.format("%s - Key:%s", "PID is not in the translation table", Key));
|
||||||
|
}
|
||||||
|
|
||||||
|
return desc.category;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getMax(String Key) throws FreeAtHomeGeneralException {
|
||||||
|
PIdContainerClass desc = MAP_PAIRING_ID.get(Key);
|
||||||
|
|
||||||
|
if (desc == null) {
|
||||||
|
throw new FreeAtHomeGeneralException(0,
|
||||||
|
String.format("%s - Key:%s", "PID is not in the translation table", Key));
|
||||||
|
}
|
||||||
|
|
||||||
|
return desc.max;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getMin(String Key) throws FreeAtHomeGeneralException {
|
||||||
|
PIdContainerClass desc = MAP_PAIRING_ID.get(Key);
|
||||||
|
|
||||||
|
if (desc == null) {
|
||||||
|
throw new FreeAtHomeGeneralException(0,
|
||||||
|
String.format("%s - Key:%s", "PID is not in the translation table", Key));
|
||||||
|
}
|
||||||
|
|
||||||
|
return desc.min;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2024 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.freeathomesystem.internal.util;
|
||||||
|
|
||||||
|
import static org.openhab.binding.freeathomesystem.internal.FreeAtHomeSystemBindingConstants.*;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.openhab.core.thing.ThingTypeUID;
|
||||||
|
import org.openhab.core.thing.type.ChannelTypeUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Andras Uhrin - Initial contribution
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class UidUtils {
|
||||||
|
|
||||||
|
public static ChannelTypeUID generateChannelTypeUID(String valueType, boolean isReadOnly) {
|
||||||
|
String channelNameString;
|
||||||
|
|
||||||
|
if (isReadOnly) {
|
||||||
|
channelNameString = valueType + "-ro";
|
||||||
|
} else {
|
||||||
|
channelNameString = valueType;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ChannelTypeUID(BINDING_ID, channelNameString);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ThingTypeUID generateThingUID() {
|
||||||
|
return new ThingTypeUID(BINDING_ID, DEVICE_TYPE_ID);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,60 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2024 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.freeathomesystem.internal.valuestateconverter;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.openhab.core.library.types.OnOffType;
|
||||||
|
import org.openhab.core.types.State;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link BinaryValueStateConverter} is a value converter for integer values with a specific mask
|
||||||
|
*
|
||||||
|
* @author Andras Uhrin - Initial contribution
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class BinaryValueStateConverter implements ValueStateConverter {
|
||||||
|
|
||||||
|
private int maskValue;
|
||||||
|
|
||||||
|
public BinaryValueStateConverter(int mask) {
|
||||||
|
maskValue = mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public State convertToState(String value) {
|
||||||
|
int intValue = Integer.decode(value);
|
||||||
|
int result;
|
||||||
|
|
||||||
|
result = intValue & maskValue;
|
||||||
|
|
||||||
|
if (maskValue == result) {
|
||||||
|
return OnOffType.ON;
|
||||||
|
} else {
|
||||||
|
return OnOffType.OFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String convertToValueString(State state) {
|
||||||
|
if (state.equals(OnOffType.ON)) {
|
||||||
|
return "1";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state.equals(OnOffType.OFF)) {
|
||||||
|
return "0";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2024 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.freeathomesystem.internal.valuestateconverter;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.openhab.core.library.types.OnOffType;
|
||||||
|
import org.openhab.core.types.State;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link DecimalValueStateConverter} is a value converter for boolean values
|
||||||
|
*
|
||||||
|
* @author Andras Uhrin - Initial contribution
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class BooleanValueStateConverter implements ValueStateConverter {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public State convertToState(String value) {
|
||||||
|
return OnOffType.from(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String convertToValueString(State state) {
|
||||||
|
if (state.equals(OnOffType.ON)) {
|
||||||
|
return "1";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state.equals(OnOffType.OFF)) {
|
||||||
|
return "0";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2024 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.freeathomesystem.internal.valuestateconverter;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.openhab.core.library.types.DecimalType;
|
||||||
|
import org.openhab.core.types.State;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link DecimalValueStateConverter} is a value converter for decimal values
|
||||||
|
*
|
||||||
|
* @author Andras Uhrin - Initial contribution
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class DecimalValueStateConverter implements ValueStateConverter {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public State convertToState(String value) {
|
||||||
|
return new DecimalType(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String convertToValueString(State state) {
|
||||||
|
return ((DecimalType) state).toString();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,79 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2024 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.freeathomesystem.internal.valuestateconverter;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.openhab.core.library.types.StopMoveType;
|
||||||
|
import org.openhab.core.library.types.StringType;
|
||||||
|
import org.openhab.core.library.types.UpDownType;
|
||||||
|
import org.openhab.core.types.Command;
|
||||||
|
import org.openhab.core.types.State;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link ShuttercontrolValueStateConverter} is a value converter for shutter movement
|
||||||
|
*
|
||||||
|
* @author Andras Uhrin - Initial contribution
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class ShuttercontrolValueStateConverter implements ValueStateConverter {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public State convertToState(String value) {
|
||||||
|
State ret = UpDownType.DOWN;
|
||||||
|
|
||||||
|
switch (value) {
|
||||||
|
default:
|
||||||
|
case "0":
|
||||||
|
ret = new StringType("STOP");
|
||||||
|
break;
|
||||||
|
case "2":
|
||||||
|
ret = UpDownType.UP;
|
||||||
|
break;
|
||||||
|
case "3":
|
||||||
|
ret = UpDownType.DOWN;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String convertToValueString(State state) {
|
||||||
|
String valueString = "0";
|
||||||
|
String stateString = "STOP";
|
||||||
|
|
||||||
|
if (state instanceof UpDownType) {
|
||||||
|
stateString = ((UpDownType) state).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (((Command) state) instanceof StopMoveType) {
|
||||||
|
stateString = "STOP";
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (stateString) {
|
||||||
|
default:
|
||||||
|
case "STOP":
|
||||||
|
valueString = "0";
|
||||||
|
break;
|
||||||
|
case "UP":
|
||||||
|
valueString = "0";
|
||||||
|
break;
|
||||||
|
case "DOWN":
|
||||||
|
valueString = "1";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return valueString;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2024 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.freeathomesystem.internal.valuestateconverter;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.openhab.core.types.State;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link ValueStateConverter} base class for the value state converters
|
||||||
|
*
|
||||||
|
* @author Andras Uhrin - Initial contribution
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public interface ValueStateConverter {
|
||||||
|
public State convertToState(String value);
|
||||||
|
|
||||||
|
public String convertToValueString(State state);
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<addon:addon id="freeathomesystem" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns:addon="https://openhab.org/schemas/addon/v1.0.0"
|
||||||
|
xsi:schemaLocation="https://openhab.org/schemas/addon/v1.0.0 https://openhab.org/schemas/addon-1.0.0.xsd">
|
||||||
|
|
||||||
|
<type>binding</type>
|
||||||
|
<name>FreeAtHomeSystem Binding</name>
|
||||||
|
<description>This is the binding for free@home system.</description>
|
||||||
|
<connection>local</connection>
|
||||||
|
</addon:addon>
|
@ -0,0 +1,652 @@
|
|||||||
|
# add-on
|
||||||
|
|
||||||
|
addon.freeathomesystem.name = FreeAtHomeSystem Binding
|
||||||
|
addon.freeathomesystem.description = This is the binding for free@home system.
|
||||||
|
|
||||||
|
# thing types
|
||||||
|
|
||||||
|
thing-type.freeathomesystem.device.label = free@home Device
|
||||||
|
thing-type.freeathomesystem.device.description = This represents the generic free@home device
|
||||||
|
thing-type.freeathomesystem.gateway.label = free@home Gateway
|
||||||
|
thing-type.freeathomesystem.gateway.description = This gateway represents the free@home Gateway
|
||||||
|
|
||||||
|
# thing types config
|
||||||
|
|
||||||
|
thing-type.config.freeathomesystem.device.deviceId.label = Device Id
|
||||||
|
thing-type.config.freeathomesystem.device.deviceId.description = This is the unique id of the free@home device (Please do not modify after the Thing is generated)
|
||||||
|
thing-type.config.freeathomesystem.gateway.group.identification.label = SysAP Setting
|
||||||
|
thing-type.config.freeathomesystem.gateway.group.identification.description = SysAP network address and user settings
|
||||||
|
thing-type.config.freeathomesystem.gateway.ipAddress.label = Sysap IP Address
|
||||||
|
thing-type.config.freeathomesystem.gateway.ipAddress.description = IP Address of the Busch-Jaeger Gateway
|
||||||
|
thing-type.config.freeathomesystem.gateway.password.label = Password
|
||||||
|
thing-type.config.freeathomesystem.gateway.password.description = Password for gateway
|
||||||
|
thing-type.config.freeathomesystem.gateway.username.label = User Name
|
||||||
|
thing-type.config.freeathomesystem.gateway.username.description = The login name
|
||||||
|
|
||||||
|
# localized error text
|
||||||
|
|
||||||
|
comm-error.not-able-open-httpconnection = Cannot open http connection, wrong password
|
||||||
|
comm-error.http-wrongpass-or-ip = Cannot open http connection, wrong password or IP address
|
||||||
|
comm-error.not-able-open-websocketconnection = Cannot open websocket connection
|
||||||
|
comm-error.general-websocket-issue = General issue in websocket connection
|
||||||
|
comm-error.websocket-keep-alive-error = Websocket keep alive error
|
||||||
|
comm-error.wrong-credentials = Wrong credentials for SysAP
|
||||||
|
comm-error.error-in-sysap-com = Error in SysAp communication
|
||||||
|
conf-error.general-binding-error = General binding error!
|
||||||
|
conf-error.datapointgroup-invalid = Datapoint group is not valid!
|
||||||
|
conf-error.inputdatapoint-invalid = Input Datapoint is not valid!
|
||||||
|
conf-error.invalid-deviceconfig = Invalid device configuration!
|
||||||
|
conf-error.invalid-bridge = Invalid bridge!
|
||||||
|
conf-error.bridge-not-configured = Bridge not configured!
|
||||||
|
conf-error.ip-address-missing = IP address is not specified!
|
||||||
|
conf-error.username-missing = User name is not specified!
|
||||||
|
conf-error.password-missing = Password is not specified!
|
||||||
|
conf-error.device-desc-null = Device description is NULL!
|
||||||
|
gen-error.no-bridge-avail = No bridge available!
|
||||||
|
|
||||||
|
# localized info text for function id
|
||||||
|
|
||||||
|
fid-dimming-sensor = Dimming sensor
|
||||||
|
fid-blind-sensor = Blind sensor
|
||||||
|
fid-stairwell-light-sensor = Stairwell light sensor
|
||||||
|
fid-force-on/off-sensor = Force On/Off sensor
|
||||||
|
fid-scene-sensor = Scene sensor
|
||||||
|
fid-switch-actuator = Switch actuator
|
||||||
|
fid-blind-actuator = Blind actuator
|
||||||
|
fid-room-temperature-controller-with-fan-speed-level = Room temperature controller with fan speed level
|
||||||
|
fid-room-temperature-controller-extension-unit = Room temperature controller extension unit
|
||||||
|
fid-wind-alarm = Wind Alarm
|
||||||
|
fid-frost-alarm = Frost Alarm
|
||||||
|
fid-rain-alarm = Rain Alarm
|
||||||
|
fid-window-sensor = Window sensor
|
||||||
|
fid-movement-detector = Movement Detector
|
||||||
|
fid-dim-actuator = Dim actuator
|
||||||
|
fid-radiator = Radiator
|
||||||
|
fid-underfloor-heating = Underfloor heating
|
||||||
|
fid-fan-coil = Fan Coil
|
||||||
|
fid-two-level-controller = Two-level controller
|
||||||
|
fid-door-opener = Door opener
|
||||||
|
fid-proxy = Proxy
|
||||||
|
fid-door-map.entry-system-call-level-actuator = Door Map.entry System Call Level Actuator
|
||||||
|
fid-door-map.entry-system-call-level-sensor = Door Map.entry System Call Level Sensor
|
||||||
|
fid-door-call = Door call
|
||||||
|
fid-automatic-door-opener = Automatic door opener
|
||||||
|
fid-corridor-light = Corridor light
|
||||||
|
fid-room-temperature-controller = Room temperature controller
|
||||||
|
fid-cooling-mode = Cooling mode
|
||||||
|
fid-heating-mode = Heating mode
|
||||||
|
fid-force-position-blind = Force-position blind
|
||||||
|
fid-auto.-heating/cooling-mode = Auto. heating/cooling mode
|
||||||
|
fid-switchover-heating/cooling = Switchover heating/cooling
|
||||||
|
fid-device-settings = Device settings
|
||||||
|
fid-dim-actuator = Dim actuator
|
||||||
|
fid-dim-actuator = Dim actuator
|
||||||
|
fid-control-element = Control element
|
||||||
|
fid-dimming-sensor = Dimming sensor
|
||||||
|
fid-blind-sensor = Blind sensor
|
||||||
|
fid-stairwell-light-sensor = Stairwell light sensor
|
||||||
|
fid-force-on/off-sensor = Force On/Off sensor
|
||||||
|
fid-force-position-blind = Force-position blind
|
||||||
|
fid-scene-sensor = Scene sensor
|
||||||
|
fid-room-temperature-controller-extension-unit = Room temperature controller extension unit
|
||||||
|
fid-fan-coil-sensor = Fan coil sensor
|
||||||
|
fid-rgb-+-warm-white/cold-white-sensor = RGB + warm white/cold white sensor
|
||||||
|
fid-rgb-sensor = RGB sensor
|
||||||
|
fid-warm-white/cold-white-sensor = Warm white/cold white sensor
|
||||||
|
fid-add.-stage-for-heating-mode = Add. stage for heating mode
|
||||||
|
fid-radiator-thermostate = Radiator thermostate
|
||||||
|
fid-room-temperature-controller-extension-unit = Room temperature controller extension unit
|
||||||
|
fid-brightness-sensor = Brightness sensor
|
||||||
|
fid-rain-sensor = Rain sensor
|
||||||
|
fid-temperature-sensor = Temperature sensor
|
||||||
|
fid-wind-sensor = Wind sensor
|
||||||
|
fid-trigger = Trigger
|
||||||
|
fid-heating-mode = Heating mode
|
||||||
|
fid-cooling-mode = Cooling mode
|
||||||
|
fid-auto.-heating/cooling-mode = Auto. heating/cooling mode
|
||||||
|
fid-two-valves-for-heating-and-cooling = Two valves for heating and cooling
|
||||||
|
fid-window/door = Window/Door
|
||||||
|
fid-abc = ABC
|
||||||
|
fid-abd = ABD
|
||||||
|
fid-acd = ACD
|
||||||
|
fid-timer-program-switch-sensor = Timer program switch sensor
|
||||||
|
fid-zone = Zone
|
||||||
|
fid-central-heating-actuator = Central heating actuator
|
||||||
|
fid-central-cooling-actuator = Central cooling actuator
|
||||||
|
fid-housekeeping = Housekeeping
|
||||||
|
fid-media-player = Media Player
|
||||||
|
fid-panel-room-temperature-controller-slave-for-battery-device = Panel Room Temperature Controller Slave For Battery Device
|
||||||
|
fid-media-player-sensor = Media Player Sensor
|
||||||
|
fid-roller-blind-actuator = Roller blind actuator
|
||||||
|
fid-attic-window-actuator = Attic window actuator
|
||||||
|
fid-awning-actuator = Awning actuator
|
||||||
|
fid-windowdoor-position-sensor = WindowDoor Position Sensor
|
||||||
|
fid-window/door-position = Window/Door position
|
||||||
|
fid-media-playback-control-sensor = Media playback control sensor
|
||||||
|
fid-media-volume-sensor = Media volume sensor
|
||||||
|
fid-dishwasher = Dishwasher
|
||||||
|
fid-laundry = Laundry
|
||||||
|
fid-dryer = Dryer
|
||||||
|
fid-oven = Oven
|
||||||
|
fid-fridge = Fridge
|
||||||
|
fid-freezer = Freezer
|
||||||
|
fid-hood = Hood
|
||||||
|
fid-coffee-machine = Coffee machine
|
||||||
|
fid-fridge/freezer = Fridge/Freezer
|
||||||
|
fid-timer-program-switch-sensor = Timer program switch sensor
|
||||||
|
fid-ceiling-fan-actuator = Ceiling fan actuator
|
||||||
|
fid-ceiling-fan-sensor = Ceiling fan sensor
|
||||||
|
fid-room-temperature-controller-with-fan-speed-level = Room temperature controller with fan speed level
|
||||||
|
fid-zone = Zone
|
||||||
|
fid-safety = Safety
|
||||||
|
fid-external-ir-sensor-bx80 = External IR Sensor BX80
|
||||||
|
fid-external-ir-sensor-vxi = External IR Sensor VXI
|
||||||
|
fid-external-ir-sensor-mini = External IR Sensor Mini
|
||||||
|
fid-external-ir-sensor-high-altitude = External IR Sensor High Altitude
|
||||||
|
fid-external-ir-sensor-curtain = External IR Sensor Curtain
|
||||||
|
fid-smoke-detector = Smoke Detector
|
||||||
|
fid-carbon-monoxide-sensor = Carbon Monoxide Sensor
|
||||||
|
fid-methane-detector = Methane Detector
|
||||||
|
fid-gas-sensor-lpg = Gas Sensor LPG
|
||||||
|
fid-flood-detection = Flood Detection
|
||||||
|
fid-secure@home-central-unit = secure@home Central Unit
|
||||||
|
fid-thermostat = Thermostat
|
||||||
|
fid-secure@home-zone-sensor = secure@home Zone Sensor
|
||||||
|
fid-slave-thermostat = Slave thermostat
|
||||||
|
fid-secure@home-integration-logic = secure@home Integration Logic
|
||||||
|
fid-add.-stage-for-cooling-mode = Add. stage for cooling mode
|
||||||
|
fid-two-level-heating-actuator = Two Level Heating Actuator
|
||||||
|
fid-two-level-cooling-actuator = Two Level Cooling Actuator
|
||||||
|
fid-zone = Zone
|
||||||
|
fid-volume-up = Volume up
|
||||||
|
fid-volume-down = Volume down
|
||||||
|
fid-play/pause = Play/pause
|
||||||
|
fid-next-favorite = Next favorite
|
||||||
|
fid-next-song = Next song
|
||||||
|
fid-previous-song = Previous song
|
||||||
|
fid-home-appliance-sensor = Home appliance sensor
|
||||||
|
fid-heat-sensor = Heat sensor
|
||||||
|
fid-zone-switching = Zone switching
|
||||||
|
fid-button-function = Button function
|
||||||
|
fid-advanced-configuration = Advanced configuration
|
||||||
|
fid-secure@home-central-unit-basic = secure@home Central Unit Basic
|
||||||
|
fid-repeater = Repeater
|
||||||
|
fid-remote-scene-control = Remote scene control
|
||||||
|
fid-window-sensor = Window sensor
|
||||||
|
fid-movement-detector = Movement Detector
|
||||||
|
fid-external-ir-sensor-curtain = External IR Sensor Curtain
|
||||||
|
fid-smoke-detector = Smoke Detector
|
||||||
|
fid-flood-detection = Flood Detection
|
||||||
|
fid-sensor-for-air-conditioning-unit = Sensor for air-conditioning unit
|
||||||
|
fid-two-point-controller-for-heating-or-cooling = Two-point controller for heating or cooling
|
||||||
|
fid-slave-thermostat = Slave thermostat
|
||||||
|
fid-wallbox = Wallbox
|
||||||
|
fid-door-lock-control = Door lock control
|
||||||
|
fid-room-temperature-controller-with-fan-speed-level = Room temperature controller with fan speed level
|
||||||
|
fid-scene-trigger = Scene trigger
|
||||||
|
fid-rule-switch = Rule Switch
|
||||||
|
fid-air-quality-sensor-pressure = Air quality sensor Pressure
|
||||||
|
fid-air-quality-sensor-co2 = Air quality sensor CO2
|
||||||
|
fid-air-quality-sensor-co = Air quality sensor CO
|
||||||
|
fid-air-quality-sensor-no2 = Air quality sensor NO2
|
||||||
|
fid-air-quality-sensor-o3 = Air quality sensor O3
|
||||||
|
fid-air-quality-sensor-pm10 = Air quality sensor PM10
|
||||||
|
fid-air-quality-sensor-pm25 = Air quality sensor PM25
|
||||||
|
fid-air-quality-sensor-voc = Air quality sensor VOC
|
||||||
|
fid-air-quality-sensor-humidity = Air quality sensor humidity
|
||||||
|
fid-movement-detector-fle = Movement detector (flex)
|
||||||
|
fid-dim-actuator-flex = Dim actuator (flex)
|
||||||
|
|
||||||
|
# localized info text for pairing id
|
||||||
|
|
||||||
|
pid-switch-on-off = Switch
|
||||||
|
pid-timed-start-stop = Timed Start/Stop
|
||||||
|
pid-force-position = Force-position
|
||||||
|
pid-scene-control = Scene Control
|
||||||
|
pid-movement-under-consideration-of-brightness = Movement under consideration of brightness
|
||||||
|
pid-presence = Presence
|
||||||
|
pid-relative-set-value = Relative Set Value
|
||||||
|
pid-absolute-set-value = Set Value
|
||||||
|
pid-night = Night
|
||||||
|
pid-invalid-string-id = invalid string id
|
||||||
|
pid-rgb-color = RGB color
|
||||||
|
pid-color-temperature = Color Temperature
|
||||||
|
pid-hsv = HSV
|
||||||
|
pid-hue = HUE
|
||||||
|
pid-saturation = Saturation
|
||||||
|
pid-move-up-down = Move Up/Down
|
||||||
|
pid-adjust-up-down = Adjust Up/Down
|
||||||
|
pid-set-absolute-position-blinds = Blinds Position
|
||||||
|
pid-set-absolute-position-slats = Slats Position
|
||||||
|
pid-wind-alarm = Wind Alarm
|
||||||
|
pid-frost-alarm = Frost Alarm
|
||||||
|
pid-rain-alarm = Rain Alarm
|
||||||
|
pid-force-position-blind = Force-position blind
|
||||||
|
pid-window-door-position = Window/Door position
|
||||||
|
pid-actuating-value-heating = Actuating Value Heating
|
||||||
|
pid-fan-level-heating = Fan Level Heating
|
||||||
|
pid-actuating-value-cooling = Actuating Value Cooling
|
||||||
|
pid-set-value-temperature = Set Value Temperature
|
||||||
|
pid-relative-set-point-temperature = Relative Setpoint Temperature
|
||||||
|
pid-window-door = Window/Door
|
||||||
|
pid-status-indication = Status
|
||||||
|
pid-fan-manual-heating-on-off = Fan Manual Heating
|
||||||
|
pid-controller-on-off = Controller
|
||||||
|
pid-relative-set-point-request = Relative Setpoint Request
|
||||||
|
pid-eco-mode-on-off-request = Eco mode
|
||||||
|
pid-comfort-temperature = Comfort Temperature
|
||||||
|
pid-fan-level-request = Fan Level
|
||||||
|
pid-fan-manual-on-off-request = Fan Switch
|
||||||
|
pid-controller-on-off-request = Controller Switch
|
||||||
|
pid-eco-mode-on-off-request = Eco mode
|
||||||
|
pid-info-on-off = Status info
|
||||||
|
pid-force-position-info = Force-position
|
||||||
|
pid-sysap-infoonoff = SysAP-InfoOnOff
|
||||||
|
pid-sysap-infoforce = SysAP-InfoForce
|
||||||
|
pid-info-actual-dimming-value = Dimming Value
|
||||||
|
pid-info-error = Error INfo
|
||||||
|
pid-sysap-infocurrentdimmingvalue = SysAP-InfoCurrentDimmingValue
|
||||||
|
pid-sysap-infoerror = SysAP-InfoError
|
||||||
|
pid-info-color-temperature = Color Temperature
|
||||||
|
pid-sysap-info-color-temperature = SysAP-Info Color Temperature
|
||||||
|
pid-info-hsv = HSV
|
||||||
|
pid-sysap-info-hsv = SysAP Info HSV
|
||||||
|
pid-info-color-mode = Color Mode
|
||||||
|
pid-sysap-info-color-mode = SysAP Info Color Mode
|
||||||
|
pid-info-move-up-down = Move Up/Down
|
||||||
|
pid-current-absolute-position-blinds-percentage = Blinds Position
|
||||||
|
pid-current-absolute-position-slats-percentage = Slats Position
|
||||||
|
pid-sysap-infomoveupdown = SysAP-InfoMoveUpDown
|
||||||
|
pid-sysap-infocurrentabsoluteblindspercentage = SysAP-InfoCurrentAbsoluteBlindsPercentage
|
||||||
|
pid-sysap-infocurrentabsoluteslatspercentage = SysAP-InfoCurrentAbsoluteSlatsPercentage
|
||||||
|
pid-measured-temperature = Measured Temperature
|
||||||
|
pid-info-value-heating = Heating Value
|
||||||
|
pid-info-value-cooling = cooling Value
|
||||||
|
pid-switchover-heating-cooling = Switchover heating/cooling
|
||||||
|
pid-actuating-fan-stage-heating = Fan Heating Control
|
||||||
|
pid-absolute-setpoint-temperature = Setpoint temperature
|
||||||
|
pid-additional-heating-value-info = Additional heating Info
|
||||||
|
pid-additional-cooling-value-info = Additional cooling Info
|
||||||
|
pid-control-value-additional-heating = Additional heating Control
|
||||||
|
pid-control-value-additional-cooling = Additional cooling Control
|
||||||
|
pid-info-actuating-fan-stage-heating = Fan Heating Info
|
||||||
|
pid-info-actuating-fan-manual-on-off-heating = Fan Manual On/Off Heating
|
||||||
|
pid-actuating-fan-stage-cooling = Fan Cooling Control
|
||||||
|
pid-info-fan-stage-cooling = Fan Cooling Info
|
||||||
|
pid-info-fan-manual-on-off-cooling = Fan Manual On/Off Cooling
|
||||||
|
pid-heating-active = Heating active
|
||||||
|
pid-cooling-active = Cooling active
|
||||||
|
pid-heating-demand = Heating demand
|
||||||
|
pid-cooling-demand = Cooling demand
|
||||||
|
pid-heating-demand-feedback-signal = Heating demand feedback
|
||||||
|
pid-cooling-demand-feedback-signal = Cooling demand feedback
|
||||||
|
pid-humidity = Humidity
|
||||||
|
pid-aux-on-off-request = Aux Switch
|
||||||
|
pid-aux-on-off-response = Aux Swicth response
|
||||||
|
pid-heating-on-off-request = Heating
|
||||||
|
pid-cooling-on-off-request = Cooling
|
||||||
|
pid-operation-mode = Operation mode
|
||||||
|
pid-swing-h-v = Swing H/V
|
||||||
|
pid-supported-features = Features
|
||||||
|
pid-extended-status-indication = Extended Status Indication
|
||||||
|
pid-extended-status-indication = Extended Status Indication
|
||||||
|
pid-aux-heating-on-off-request = Aux Heating
|
||||||
|
pid-emergency-heating-on-off-request = Emergency Heating
|
||||||
|
pid-relative-fan-speed-control = Relative fan speed
|
||||||
|
pid-absolute-fan-speed-control = Fan speed
|
||||||
|
pid-info-absolute-fan-speed = Fan speed feedback
|
||||||
|
pid-sysap-infoactualfanspeed = SysAP-InfoActualFanSpeed
|
||||||
|
pid-notification-flags = Notification flags
|
||||||
|
pid-power-rc = Power RC
|
||||||
|
pid-power-rh = Power RH
|
||||||
|
pid-proximity-status = Proximity status
|
||||||
|
pid-brightness-sensor = Brightness
|
||||||
|
pid-last-touch = Last touch
|
||||||
|
pid-led-backlighting-night-mode = LED backlighting
|
||||||
|
pid-locator-beep = Locator beep
|
||||||
|
pid-switch-test-alarm = Switch test alarm
|
||||||
|
pid-fire-alarm-active = Fire alarm
|
||||||
|
pid-outside-temperature = Outside temperature
|
||||||
|
pid-wind-force = Wind force
|
||||||
|
pid-brightness-alarm = Brightness alarm
|
||||||
|
pid-lux-value = Lux value
|
||||||
|
pid-wind-speed = Wind speed
|
||||||
|
pid-rain-detection = Rain detection
|
||||||
|
pid-rain-sensor-frequency = Rain sensor frequency
|
||||||
|
pid-play = Play
|
||||||
|
pid-pause = Pause
|
||||||
|
pid-next = Next
|
||||||
|
pid-previous = Previous
|
||||||
|
pid-play-mode = Play mode
|
||||||
|
pid-mute = Mute
|
||||||
|
pid-relative-volume-control = Relative volume control
|
||||||
|
pid-absolute-volume-control = Absolute volume control
|
||||||
|
pid-group-membership = Group membership
|
||||||
|
pid-play-favorite = Play favorite
|
||||||
|
pid-play-next-favorite = Play next favorite
|
||||||
|
pid-playback-status = Playback status
|
||||||
|
pid-current-item-metadata-info = Current item metadata
|
||||||
|
pid-info-mute = Mute Info
|
||||||
|
pid-info-actual-volume = Actual volume
|
||||||
|
pid-allowed-playback-actions = Playback actions
|
||||||
|
pid-info-group-membership = Group membership Info
|
||||||
|
pid-info-playing-favorite = Playing favorite Info
|
||||||
|
pid-absolute-group-volume-control = Group Volume
|
||||||
|
pid-info-absolute-group-volume = Group Volume INfo
|
||||||
|
pid-media-source = Media source
|
||||||
|
pid-solar-power-production = Power production
|
||||||
|
pid-inverter-output-power = Inverter output power
|
||||||
|
pid-solar-energy-(today) = Solar energy (today)
|
||||||
|
pid-injected-energy-(today) = Injected energy (today)
|
||||||
|
pid-purchased-energy-(today) = Purchased energy (today)
|
||||||
|
pid-inverter-alarm = Inverter alarm
|
||||||
|
pid-self-consumption = Self-consumption
|
||||||
|
pid-self-sufficiency = Self-sufficiency
|
||||||
|
pid-home-power-consumption = Home power consumption
|
||||||
|
pid-power-to-grid = Power to grid
|
||||||
|
pid-consumed-energy-(today) = Consumed energy (today)
|
||||||
|
pid-meter-alarm = Meter alarm
|
||||||
|
pid-battery-level = Battery level
|
||||||
|
pid-battery-power = Battery power
|
||||||
|
pid-boost = Boost
|
||||||
|
pid-stop-charging-reuqest = Stop charging
|
||||||
|
pid-enable-charging-reuqest = Enable charging
|
||||||
|
pid-info-boost = Boost Info
|
||||||
|
pid-info-wallbox-status = Wallbox status
|
||||||
|
pid-info-charging = Charging INfo
|
||||||
|
pid-info-charging-enabled = Charging enabled
|
||||||
|
pid-info-installed-power = Installed power
|
||||||
|
pid-info-transmitted-energy = Transmitted energy
|
||||||
|
pid-info-car-range = Car range
|
||||||
|
pid-info-charging-duration = Charging duration
|
||||||
|
pid-info-current-limit = Current limit
|
||||||
|
pid-info-current-limit-for-group = Current limit for group
|
||||||
|
pid-album-cover-url = Cover
|
||||||
|
pid-secure@home-central-unit = secure@home Central Unit
|
||||||
|
pid-domusdisarmcounter = DomusDisarmCounter
|
||||||
|
pid-intrusion-alarm = Intrusion Alarm
|
||||||
|
pid-safety-alarm = Safety Alarm
|
||||||
|
pid-infoconfigurationstatus = InfoConfigurationStatus
|
||||||
|
pid-enable-configuration = Enable configuration
|
||||||
|
pid-disarming-led = Disarming LED
|
||||||
|
pid-aes-key = AES Key
|
||||||
|
pid-zone-status = Zone status
|
||||||
|
pid-time = Time
|
||||||
|
pid-start-stop = Start / Stop
|
||||||
|
pid-pause-resume = Pause / Resume
|
||||||
|
pid-select-program = Select program
|
||||||
|
pid-delayed-start-time = Delayed start time
|
||||||
|
pid-info-status = Status
|
||||||
|
pid-info-remote-start-enabled = Remote start enabled
|
||||||
|
pid-info-program = Program
|
||||||
|
pid-info-finish-time = Finish time
|
||||||
|
pid-info-delayed-start = Delayed start
|
||||||
|
pid-info-door = Door
|
||||||
|
pid-info-door-alarm = Door alarm
|
||||||
|
pid-switch-supercool = Supercool Info
|
||||||
|
pid-switch-superfreeze = Superfreeze Info
|
||||||
|
pid-info-switch-supercool = Supercool switch
|
||||||
|
pid-info-switch-superfreeze = Superfreeze switch
|
||||||
|
pid-measured-temperature = Measured Temperature
|
||||||
|
pid-set-value-temperature = Set Value Temperature
|
||||||
|
pid-change-operation = Operation
|
||||||
|
pid-detailed-status-info = Status
|
||||||
|
pid-info-remaining-time = Remaining time
|
||||||
|
pid-time-of-last-status-change = Time of last change
|
||||||
|
pid-lock-unlock-door-command = Door lock
|
||||||
|
pid-info-locked-unlocked = Door Status
|
||||||
|
pid-time = Time
|
||||||
|
pid-date = Date
|
||||||
|
pid-notification = Notification
|
||||||
|
pid-switch-entity-on-off = Switch
|
||||||
|
pid-info-switch-entity-on-off = Switch feedback
|
||||||
|
pid-consistency-tag = Consistency Tag
|
||||||
|
pid-battery-status = Battery Status
|
||||||
|
pid-stay-awake = Stay awake!
|
||||||
|
pid-proxy-switch = Proxy switch
|
||||||
|
pid-proxy1 = Proxy 1Byte
|
||||||
|
pid-proxy2 = Proxy 2Byte
|
||||||
|
pid-proxy4 = Proxy 4Byte
|
||||||
|
pid-cyclic-sleep-time = Sleep time
|
||||||
|
pid-presence = Presence
|
||||||
|
pid-measured-temperature-1 = Measured temperature
|
||||||
|
pid-standby-statistics = Standby Statistics
|
||||||
|
pid-heartbeat-delay = Heartbeat delay
|
||||||
|
pid-info-heartbeat-delay = Heartbeat delay
|
||||||
|
pid-measured-temperature-1 = Measured temperature
|
||||||
|
pid-measured-temperature-2 = Measured temperature
|
||||||
|
pid-measured-temperature-3 = Measured temperature
|
||||||
|
pid-measured-temperature-4 = Measured temperature
|
||||||
|
pid-air-quality-pressure-value = Pressure value
|
||||||
|
pid-air-quality-co2-value = CO2 value
|
||||||
|
pid-air-quality-co-value = CO value
|
||||||
|
pid-air-quality-no2-value = NO2 value
|
||||||
|
pid-air-quality-o3-value = O3 value
|
||||||
|
pid-air-quality-pm10-value = PM10 value
|
||||||
|
pid-air-quality-pm25-value = PM25 value
|
||||||
|
pid-air-quality-voc-value = VOC value
|
||||||
|
|
||||||
|
# localized info text for pairing id description
|
||||||
|
|
||||||
|
pid-switch-on-off-text = Actual value of the switch
|
||||||
|
pid-timed-start-stop-text = Switch for staircase lightning or movement detection
|
||||||
|
pid-force-position-text = Forces value dependent high priority on or off state
|
||||||
|
pid-scene-control-text = Recall or learn the set value related to encoded scene number
|
||||||
|
pid-movement-under-consideration-of-brightness-text = Activation of an autonomous switch off function triggered by an movement detector
|
||||||
|
pid-presence-text = Presence triggered by a movement detector to be used by other devices
|
||||||
|
pid-relative-set-value-text = Relative dimming value
|
||||||
|
pid-absolute-set-value-text = Controls the set value
|
||||||
|
pid-night-text = Toggle between day and night (where day = 0 / night = 1)
|
||||||
|
pid-invalid-string-id-text = Resets load failures / short circuits / etc
|
||||||
|
pid-rgb-color-text = RGB Color value of the light
|
||||||
|
pid-color-temperature-text = Color temperature value of the light
|
||||||
|
pid-hue-text = Hue value of the light
|
||||||
|
pid-saturation-text = Saturation value of the light
|
||||||
|
pid-move-up-down-text = Moves sunblind up and down
|
||||||
|
pid-adjust-up-down-text = Stops the sunblind and to step it up/down
|
||||||
|
pid-set-absolute-position-blinds-text = Moves the sunblinds into a specified position
|
||||||
|
pid-set-absolute-position-slats-text = Moves the slats into a specified position
|
||||||
|
pid-rain-alarm-text = State of the rain sensor (sent cyclically and on COV)
|
||||||
|
pid-force-position-blind-text = Forces value dependent high priority up or down state
|
||||||
|
pid-window-door-position-text = Delivers position for Window/Door (Open / Tilted / Closed)
|
||||||
|
pid-actuating-value-heating-text = Determines the through flow volume of the control valve
|
||||||
|
pid-fan-level-heating-text = Display value of the fan coil speed. (0=off / 1=lowest - 5=fastest)
|
||||||
|
pid-actuating-value-cooling-text = Determines the through flow volume of the control valve
|
||||||
|
pid-set-value-temperature-text = Defines the displayed set point temperature of the system
|
||||||
|
pid-relative-set-point-temperature-text = Defines the relative set point temperature of the system
|
||||||
|
pid-window-door-text = Status indication - Open = 1 / closed = 0
|
||||||
|
pid-status-indication-text = States indication - on/off heating/cool
|
||||||
|
pid-fan-manual-heating-on-off-text = Switches Fan in manual control mode (master to slave)
|
||||||
|
pid-controller-on-off-text = Switches controller on or off. Off means protection mode
|
||||||
|
pid-relative-set-point-request-text = Request for a new relative set point value
|
||||||
|
pid-eco-mode-on-off-request-text = Switches eco mode on or off
|
||||||
|
pid-comfort-temperature-text = Sends the current comfort temperature
|
||||||
|
pid-fan-level-request-text = Request for a new manual fan stage
|
||||||
|
pid-fan-manual-on-off-request-text = WARNING: DO NOT USE!!!! Request for switching fan in manual/auto mode
|
||||||
|
pid-controller-on-off-request-text = Request for switching controller on or off. Off means protection mode
|
||||||
|
pid-eco-mode-on-off-request-text = Indicates ECO mode
|
||||||
|
pid-info-on-off-text = Reflects the binary state of the actuator
|
||||||
|
pid-force-position-info-text = Indicates the cause of forced operation (0 = not forced)
|
||||||
|
pid-sysap-infoonoff-text = Reflects the binary state of the actuator group
|
||||||
|
pid-sysap-infoforce-text = Indicates whether the actuator group is forced (1) or not forced (0)
|
||||||
|
pid-info-actual-dimming-value-text = Reflects the actual value of the actuator
|
||||||
|
pid-info-error-text = Indicates load failures / short circuits / etc
|
||||||
|
pid-sysap-infocurrentdimmingvalue-text = Reflects the actual value of the actuator group
|
||||||
|
pid-sysap-infoerror-text = Indicates load failures / short circuits / etc
|
||||||
|
pid-info-color-temperature-text = Color temperature
|
||||||
|
pid-sysap-info-color-temperature-text = Color temperature
|
||||||
|
pid-info-hsv-text = Hue (2 Byte) Saturation (1 Byte)
|
||||||
|
pid-sysap-info-hsv-text = Hue (2 Byte) Saturation (1 Byte)
|
||||||
|
pid-info-color-mode-text = Hsv or color mode
|
||||||
|
pid-sysap-info-color-mode-text = Hsv or color mode info
|
||||||
|
pid-info-move-up-down-text = Indicates the status of moving and last moving direction
|
||||||
|
pid-current-absolute-position-blinds-percentage-text = Indicate the current position of the sunblinds in percentage
|
||||||
|
pid-current-absolute-position-slats-percentage-text = Indicate the current position of the slats in percentage
|
||||||
|
pid-sysap-infomoveupdown-text = Indicates the status of moving and last moving direction of the actuator group
|
||||||
|
pid-sysap-infocurrentabsoluteblindspercentage-text = Indicate the current position of the sunblinds in percentage of the actuator group
|
||||||
|
pid-sysap-infocurrentabsoluteslatspercentage-text = Indicate the current position of the slats in percentage of the actuator group
|
||||||
|
pid-measured-temperature-text = Indicates the actual measured temperature
|
||||||
|
pid-info-value-heating-text = States the current flow volume of the control valve
|
||||||
|
pid-info-value-cooling-text = States the current flow volume of the control valve
|
||||||
|
pid-switchover-heating-cooling-text = Switch between heating and cooling: heating = 0 / cooling = 1
|
||||||
|
pid-actuating-fan-stage-heating-text = Requests a new manual fan stage from actuator in heating mode
|
||||||
|
pid-absolute-setpoint-temperature-text = Set point temperature input for timer
|
||||||
|
pid-additional-heating-value-info-text = Heating feedback
|
||||||
|
pid-additional-cooling-value-info-text = Cooling feedback
|
||||||
|
pid-info-actuating-fan-stage-heating-text = Feedback from actuating fan stage
|
||||||
|
pid-info-actuating-fan-manual-on-off-heating-text = Feedback from actuating fan stage (manual on/off)
|
||||||
|
pid-actuating-fan-stage-cooling-text = Requests a new manual fan stage from actuator in cooling mode
|
||||||
|
pid-info-fan-stage-cooling-text = Feedback for current fan stage in cooling mode
|
||||||
|
pid-info-fan-manual-on-off-cooling-text = Feedback for manual fan control cooling mode
|
||||||
|
pid-heating-active-text = Heating active
|
||||||
|
pid-cooling-active-text = Cooling active
|
||||||
|
pid-heating-demand-text = Heating demand
|
||||||
|
pid-cooling-demand-text = Cooling demand
|
||||||
|
pid-heating-demand-feedback-signal-text = Heating demand feedback signal
|
||||||
|
pid-cooling-demand-feedback-signal-text = Cooling demand feedback signal
|
||||||
|
pid-humidity-text = Measured Humidity
|
||||||
|
pid-aux-on-off-request-text = Aux On/Off
|
||||||
|
pid-aux-on-off-response-text = Aux On/Off response
|
||||||
|
pid-heating-on-off-request-text = Heating On/Off
|
||||||
|
pid-cooling-on-off-request-text = Cooling On/Off
|
||||||
|
pid-operation-mode-text = Operation mode
|
||||||
|
pid-swing-h-v-text = Swing H/V
|
||||||
|
pid-supported-features-text = Supported features
|
||||||
|
pid-extended-status-indication-text = Extended Status Indication
|
||||||
|
pid-aux-heating-on-off-request-text = Aux Heating On Off Reques
|
||||||
|
pid-emergency-heating-on-off-request-text = Emergency Heating On Off Request
|
||||||
|
pid-relative-fan-speed-control-text = Relative control of the set value
|
||||||
|
pid-absolute-fan-speed-control-text = Absolute control of the set value
|
||||||
|
pid-info-absolute-fan-speed-text = Reflects the actual value of the actuator
|
||||||
|
pid-sysap-infoactualfanspeed-text = Reflects the actual value of the actuator
|
||||||
|
pid-notification-flags-text = Notifications of RF devices (e. g. Battery low)
|
||||||
|
pid-power-rc-text = Bool Value 1
|
||||||
|
pid-power-rh-text = Bool Value 2
|
||||||
|
pid-proximity-status-text = Bool Value 3
|
||||||
|
pid-brightness-sensor-text = Scaling Value 1
|
||||||
|
pid-last-touch-text = Scaling Value 2
|
||||||
|
pid-led-backlighting-night-mode-text = Scaling Value 3
|
||||||
|
pid-locator-beep-text = Locator Beep
|
||||||
|
pid-switch-test-alarm-text = Switch Test Alarm
|
||||||
|
pid-fire-alarm-active-text = Fire-Alarm Active
|
||||||
|
pid-outside-temperature-text = Outdoor Temperature
|
||||||
|
pid-wind-force-text = Wind force
|
||||||
|
pid-brightness-alarm-text = Brightness alarm
|
||||||
|
pid-lux-value-text = Weatherstation brightness level
|
||||||
|
pid-wind-speed-text = Wind speed
|
||||||
|
pid-wind-alarm-text = Triggers if the wind speed is higher than the threshold
|
||||||
|
pid-frost-alarm-text = Triggers if the temperature is lower than the threshold
|
||||||
|
pid-rain-detection-text = Rain detection
|
||||||
|
pid-rain-sensor-frequency-text = Rain sensor frequency
|
||||||
|
pid-play-text = Start playing
|
||||||
|
pid-pause-text = Pause/Stop playing
|
||||||
|
pid-next-text = Play next title
|
||||||
|
pid-previous-text = Play previous title
|
||||||
|
pid-play-mode-text = Play mode (shuffle / repeat)
|
||||||
|
pid-relative-volume-control-text = Relative volume control. See also relative dimming
|
||||||
|
pid-absolute-volume-control-text = Set player volume
|
||||||
|
pid-group-membership-text = Group membership
|
||||||
|
pid-play-favorite-text = Play favorite
|
||||||
|
pid-play-next-favorite-text = Play next favorite
|
||||||
|
pid-playback-status-text = Playback status
|
||||||
|
pid-current-item-metadata-info-text = Current item metadata info
|
||||||
|
pid-info-mute-text = Info mute
|
||||||
|
pid-info-actual-volume-text = Info actual volume
|
||||||
|
pid-allowed-playback-actions-text = Allowed playback actions
|
||||||
|
pid-info-playing-favorite-text = Info playing favorite
|
||||||
|
pid-absolute-group-volume-control-text = Group Volume Control
|
||||||
|
pid-info-absolute-group-volume-text = Info Group Volume
|
||||||
|
pid-media-source-text = Media source
|
||||||
|
pid-solar-power-production-text = Power from the sun
|
||||||
|
pid-inverter-output-power-text = Output power of inverter (pbatt+Psun)
|
||||||
|
pid-solar-energy-(today)-text = Produced Energy
|
||||||
|
pid-injected-energy-(today)-text = Energy into the grid
|
||||||
|
pid-purchased-energy-(today)-text = Energy from the grid
|
||||||
|
pid-inverter-alarm-text = Inverter is working in stand alone mode
|
||||||
|
pid-self-consumption-text = production PV/ Total consumption
|
||||||
|
pid-self-sufficiency-text = Consumption from PV/ Total consumption
|
||||||
|
pid-home-power-consumption-text = Power in home (PV and grid)
|
||||||
|
pid-power-to-grid-text = Power from and to the grid: Purchased (less than 0), Injection (more than 0)
|
||||||
|
pid-consumed-energy-(today)-text = Energy bought from grid per day
|
||||||
|
pid-meter-alarm-text = Meter communication loss
|
||||||
|
pid-battery-level-text = Battery level
|
||||||
|
pid-battery-power-text = Batter power: Discharge (less then 0), Charge (more then 0)
|
||||||
|
pid-boost-text = Boos status - 1: Boost enable request, 0: boost disable request
|
||||||
|
pid-stop-charging-reuqest-text = Stop charging request - 1: Stop charging session requested, 0: n/a, will be resetted when cable is unplugged
|
||||||
|
pid-enable-charging-reuqest-text = Enable charging - 1: Enable charging when cable is plugged in, 0: Disable next charging session but charge until cable is plugged
|
||||||
|
pid-info-boost-text = Boots info - 1: Boost enabled, 0: boost disabled
|
||||||
|
pid-info-wallbox-status-text = Wallbox status 00000001: car plugged in, 00000002: Authorization granted, 00000004: Not charging, battery fully loaded, 40000000: charging stopped due to blackout prevention, 80000000: Ground fault error
|
||||||
|
pid-info-charging-text = Charging status - 1: Charging, 0: Not charging
|
||||||
|
pid-info-charging-enabled-text = Charging status - 1: Charging enabled for next session, 0: Charging disabled for next session
|
||||||
|
pid-info-installed-power-text = Installed power (e.g. 20 kW)
|
||||||
|
pid-info-transmitted-energy-text = Energy transmitted so far per session (in Wh)
|
||||||
|
pid-info-car-range-text = Car range in km per sessions
|
||||||
|
pid-info-charging-duration-text = Start of charging session (in minutes in UTC)
|
||||||
|
pid-info-current-limit-text = Limit for charger (in kW)
|
||||||
|
pid-info-current-limit-for-group-text = Limit for group of charger (in kW)
|
||||||
|
pid-album-cover-url-text = Album cover URL
|
||||||
|
pid-secure@home-central-unit-text = Encrypted control datapoint for domus alarm center
|
||||||
|
pid-domusdisarmcounter-text = Info about the next counter to disarm the system
|
||||||
|
pid-intrusion-alarm-text = Intrusion alarm active
|
||||||
|
pid-safety-alarm-text = Safety Alarm active
|
||||||
|
pid-infoconfigurationstatus-text = Domus alarm device negative feedback and configuration info.
|
||||||
|
pid-enable-configuration-text = Encrypted control datapoint for entering configuration mode
|
||||||
|
pid-disarming-led-text = Arm/Disarm a Zone
|
||||||
|
pid-aes-key-text = Manufacturer ID + Serial + AES Key
|
||||||
|
pid-zone-status-text = Zone status
|
||||||
|
pid-time-text = Absolute number of seconds when the zone will be armed
|
||||||
|
pid-start-stop-text = Starts / Stops operation
|
||||||
|
pid-pause-resume-text = Pause / Resume
|
||||||
|
pid-select-program-text = Select program
|
||||||
|
pid-delayed-start-time-text = Delayed start time
|
||||||
|
pid-info-status-text = Info status
|
||||||
|
pid-info-remote-start-enabled-text = Info remote start enabled
|
||||||
|
pid-info-program-text = Info program
|
||||||
|
pid-info-finish-time-text = Info finish time
|
||||||
|
pid-info-delayed-start-text = Info delayed start
|
||||||
|
pid-info-door-text = Info door
|
||||||
|
pid-info-door-alarm-text = Info door alarm
|
||||||
|
pid-switch-supercool-text = Switch supercool
|
||||||
|
pid-switch-superfreeze-text = Switch superfreeze
|
||||||
|
pid-info-switch-supercool-text = Info switch supercool
|
||||||
|
pid-info-switch-superfreeze-text = Info switch superfreeze
|
||||||
|
pid-measured-temperature-text = Measured Temperature
|
||||||
|
pid-measured-temperature-text = Measured Temperature
|
||||||
|
pid-set-value-temperature-text = Set Value Temperature
|
||||||
|
pid-set-value-temperature-text = Set Value Temperature
|
||||||
|
pid-change-operation-text = Change operation
|
||||||
|
pid-detailed-status-info-text = Detailed status info
|
||||||
|
pid-info-remaining-time-text = Remaining time till status change (start, finish, etc.)
|
||||||
|
pid-time-of-last-status-change-text = Time of last status change (start, finish, etc.)
|
||||||
|
pid-lock-unlock-door-command-text = Lock/Unlock door command (1 Bit)
|
||||||
|
pid-info-locked-unlocked-text = Info Lock/Unlock door(1 Bit)
|
||||||
|
pid-time-text = Current local time
|
||||||
|
pid-date-text = Current local date
|
||||||
|
pid-notification-text = Notification from message center
|
||||||
|
pid-switch-entity-on-off-text = Entity control e.g. activate an alert or timer program
|
||||||
|
pid-info-switch-entity-on-off-text = Reflects the active state of an entity e.g. alert or timer program
|
||||||
|
pid-consistency-tag-text = Notifications of RF devices (e. g. Battery low)
|
||||||
|
pid-battery-status-text = Notifications of RF devices (e. g. Battery low)
|
||||||
|
pid-stay-awake-text = Notifications of RF devices (e. g. Battery low)
|
||||||
|
pid-proxy-switch-text = Proxy switch
|
||||||
|
pid-proxy1-text = Proxy, 1 byte
|
||||||
|
pid-proxy2-text = Proxy, 2 byte
|
||||||
|
pid-proxy4-text = Proxy, 4 byte
|
||||||
|
pid-cyclic-sleep-time-text = Time of sleep cycles
|
||||||
|
pid-presence-text = SysAP presence
|
||||||
|
pid-measured-temperature-1-text = SysAP temperature
|
||||||
|
pid-standby-statistics-text = Statistics about standby usage for battery devices
|
||||||
|
pid-heartbeat-delay-text = Time period between two heartbeats
|
||||||
|
pid-info-heartbeat-delay-text = Time period between two heartbeats
|
||||||
|
pid-measured-temperature-1-text = For debug purposes
|
||||||
|
pid-measured-temperature-2-text = For debug purposes
|
||||||
|
pid-measured-temperature-3-text = For debug purposes
|
||||||
|
pid-measured-temperature-4-text = For debug purposes
|
||||||
|
pid-air-quality-pressure-value-text = Air quality sensor value - Pressure value
|
||||||
|
pid-air-quality-co2-value-text = Air quality sensor value - CO2 value
|
||||||
|
pid-air-quality-co-value-text = Air quality sensor value - CO value
|
||||||
|
pid-air-quality-no2-value-text = Air quality sensor value - NO2 value
|
||||||
|
pid-air-quality-o3-value-text = Air quality sensor value - O3 value
|
||||||
|
pid-air-quality-pm10-value-text = Air quality sensor value - PM10 value
|
||||||
|
pid-air-quality-pm25-value-text = Air quality sensor value - PM25 value
|
||||||
|
pid-air-quality-voc-value-text = Air quality sensor value - VOC value
|
@ -0,0 +1,35 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<thing:thing-descriptions bindingId="freeathomesystem"
|
||||||
|
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">
|
||||||
|
|
||||||
|
<bridge-type id="gateway">
|
||||||
|
<label>free@home Gateway</label>
|
||||||
|
<description>This gateway represents the free@home Gateway</description>
|
||||||
|
|
||||||
|
<config-description>
|
||||||
|
<parameter-group name="identification">
|
||||||
|
<label>SysAP Setting</label>
|
||||||
|
<description>SysAP network address and user settings</description>
|
||||||
|
<advanced>false</advanced>
|
||||||
|
</parameter-group>
|
||||||
|
|
||||||
|
<parameter name="ipAddress" type="text" required="true" groupName="identification">
|
||||||
|
<context>network-address</context>
|
||||||
|
<label>Sysap IP Address</label>
|
||||||
|
<description>IP Address of the Busch-Jaeger Gateway</description>
|
||||||
|
</parameter>
|
||||||
|
<parameter name="username" type="text" required="true" groupName="identification">
|
||||||
|
<label>User Name</label>
|
||||||
|
<description>The login name</description>
|
||||||
|
</parameter>
|
||||||
|
<parameter name="password" type="text" required="true" groupName="identification">
|
||||||
|
<label>Password</label>
|
||||||
|
<context>password</context>
|
||||||
|
<description>Password for gateway</description>
|
||||||
|
</parameter>
|
||||||
|
|
||||||
|
</config-description>
|
||||||
|
</bridge-type>
|
||||||
|
</thing:thing-descriptions>
|
@ -0,0 +1,24 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<thing:thing-descriptions bindingId="freeathomesystem"
|
||||||
|
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="device" listed="false">
|
||||||
|
<supported-bridge-type-refs>
|
||||||
|
<bridge-type-ref id="gateway"/>
|
||||||
|
</supported-bridge-type-refs>
|
||||||
|
<label>free@home Device</label>
|
||||||
|
<description>This represents the generic free@home device</description>
|
||||||
|
<properties>
|
||||||
|
<property name="vendor">Busch&Jäger - ABB</property>
|
||||||
|
<property name="modelId">Generic free@home Device</property>
|
||||||
|
</properties>
|
||||||
|
<representation-property>deviceId</representation-property>
|
||||||
|
<config-description>
|
||||||
|
<parameter name="deviceId" type="text" required="true">
|
||||||
|
<label>Device Id</label>
|
||||||
|
<description>This is the unique id of the free@home device (Please do not modify after the Thing is generated)</description>
|
||||||
|
</parameter>
|
||||||
|
</config-description>
|
||||||
|
</thing-type>
|
||||||
|
</thing:thing-descriptions>
|
@ -146,6 +146,7 @@
|
|||||||
<module>org.openhab.binding.folderwatcher</module>
|
<module>org.openhab.binding.folderwatcher</module>
|
||||||
<module>org.openhab.binding.folding</module>
|
<module>org.openhab.binding.folding</module>
|
||||||
<module>org.openhab.binding.foobot</module>
|
<module>org.openhab.binding.foobot</module>
|
||||||
|
<module>org.openhab.binding.freeathomesystem</module>
|
||||||
<module>org.openhab.binding.freebox</module>
|
<module>org.openhab.binding.freebox</module>
|
||||||
<module>org.openhab.binding.freeboxos</module>
|
<module>org.openhab.binding.freeboxos</module>
|
||||||
<module>org.openhab.binding.freecurrency</module>
|
<module>org.openhab.binding.freecurrency</module>
|
||||||
|
Loading…
Reference in New Issue
Block a user