mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-01-10 15:11:59 +01:00
[avmfritz] Added support for DECT500 and HAN-FUN bulbs (#11348)
* Added support for DECT500 and HAN-FUN bulbs Signed-off-by: Christoph Weitkamp <github@christophweitkamp.de> * Incorporated comment from review Signed-off-by: Christoph Weitkamp <github@christophweitkamp.de>
This commit is contained in:
parent
406f9c1364
commit
58a094b09a
@ -67,6 +67,10 @@ The FRITZ!DECT 400 supports a configurable button to trigger short or long press
|
||||
Beside four customizable buttons the FRITZ!DECT 440 supports temperature readings.
|
||||
** NOTE: ** FRITZ!DECT 440 now uses Channel Groups to group its Channels like `device#battery_level`, `device#battery_low` for device information, `sensors#temperature` for sensor data and `top-left`, `bottom-left`, `top-right` and `bottom-right` combined with `press` and `last_change` (see [Full Example](#full-example))
|
||||
|
||||
### FRITZ!DECT 500
|
||||
|
||||
The [FRITZ!DECT 500](https://avm.de/produkte/fritzdect/fritzdect-500/) is a dimmable colorized light bulb.
|
||||
|
||||
#### Supported Channel Groups
|
||||
|
||||
| Channel Group ID | Description | Available on thing |
|
||||
@ -178,7 +182,7 @@ The AIN (actor identification number) can be found in the FRITZ!Box interface ->
|
||||
| power | Number:Power | Current power consumption | FRITZ!DECT 210, FRITZ!DECT 200, FRITZ!Powerline 546E |
|
||||
| voltage | Number:ElectricPotential | Current voltage - FRITZ!OS 7 | FRITZ!DECT 210, FRITZ!DECT 200, FRITZ!Powerline 546E |
|
||||
| outlet | Switch | Switchable outlet (ON/OFF) | FRITZ!DECT 210, FRITZ!DECT 200, FRITZ!Powerline 546E |
|
||||
| on_off | Switch | Switchable device (ON/OFF) | HAN_FUN_ON_OFF |
|
||||
| on_off | Switch | Switchable device (ON/OFF) | FRITZ!DECT 500, HAN_FUN_ON_OFF |
|
||||
| actual_temp | Number:Temperature | Current temperature of heating thermostat | FRITZ!DECT 301, FRITZ!DECT 300, Comet DECT |
|
||||
| set_temp | Number:Temperature | Set Temperature of heating thermostat | FRITZ!DECT 301, FRITZ!DECT 300, Comet DECT |
|
||||
| eco_temp | Number:Temperature | Eco Temperature of heating thermostat | FRITZ!DECT 301, FRITZ!DECT 300, Comet DECT |
|
||||
|
@ -12,7 +12,6 @@
|
||||
*/
|
||||
package org.openhab.binding.avmfritz.internal;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
@ -41,6 +40,7 @@ public class AVMFritzBindingConstants {
|
||||
public static final String POWERLINE_MODEL_NAME = "FRITZ!Powerline";
|
||||
|
||||
// List of main device types
|
||||
public static final String DEVICE_DECT500 = "FRITZ_DECT_500";
|
||||
public static final String DEVICE_DECT400 = "FRITZ_DECT_400";
|
||||
public static final String DEVICE_DECT440 = "FRITZ_DECT_440";
|
||||
public static final String DEVICE_DECT301 = "FRITZ_DECT_301";
|
||||
@ -62,6 +62,7 @@ public class AVMFritzBindingConstants {
|
||||
|
||||
// List of all Thing Type UIDs
|
||||
public static final ThingTypeUID BRIDGE_THING_TYPE = new ThingTypeUID(BINDING_ID, BRIDGE_FRITZBOX);
|
||||
public static final ThingTypeUID DECT500_THING_TYPE = new ThingTypeUID(BINDING_ID, DEVICE_DECT500);
|
||||
public static final ThingTypeUID DECT400_THING_TYPE = new ThingTypeUID(BINDING_ID, DEVICE_DECT400);
|
||||
public static final ThingTypeUID DECT440_THING_TYPE = new ThingTypeUID(BINDING_ID, DEVICE_DECT440);
|
||||
public static final ThingTypeUID DECT301_THING_TYPE = new ThingTypeUID(BINDING_ID, DEVICE_DECT301);
|
||||
@ -132,6 +133,8 @@ public class AVMFritzBindingConstants {
|
||||
public static final String CHANNEL_LAST_CHANGE = "last_change";
|
||||
public static final String CHANNEL_ROLLERSHUTTER = "rollershutter";
|
||||
public static final String CHANNEL_ON_OFF = "on_off";
|
||||
public static final String CHANNEL_COLOR = "color";
|
||||
public static final String CHANNEL_BRIGHTNESS = "brightness";
|
||||
|
||||
// List of all Channel config ids
|
||||
public static final String CONFIG_CHANNEL_TEMP_OFFSET = "offset";
|
||||
@ -164,6 +167,8 @@ public class AVMFritzBindingConstants {
|
||||
public static final String MODE_WINDOW_OPEN = "WINDOW_OPEN";
|
||||
public static final String MODE_UNKNOWN = "UNKNOWN";
|
||||
|
||||
public static final Set<ThingTypeUID> SUPPORTED_LIGHTING_THING_TYPES = Set.of(DECT500_THING_TYPE);
|
||||
|
||||
public static final Set<ThingTypeUID> SUPPORTED_BUTTON_THING_TYPES_UIDS = Set.of(DECT400_THING_TYPE,
|
||||
DECT440_THING_TYPE, HAN_FUN_SWITCH_THING_TYPE);
|
||||
|
||||
@ -180,8 +185,8 @@ public class AVMFritzBindingConstants {
|
||||
public static final Set<ThingTypeUID> SUPPORTED_BRIDGE_THING_TYPES_UIDS = Set.of(BRIDGE_THING_TYPE,
|
||||
PL546E_STANDALONE_THING_TYPE);
|
||||
|
||||
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Collections.unmodifiableSet(Stream
|
||||
.of(SUPPORTED_BUTTON_THING_TYPES_UIDS, SUPPORTED_HEATING_THING_TYPES, SUPPORTED_DEVICE_THING_TYPES_UIDS,
|
||||
SUPPORTED_GROUP_THING_TYPES_UIDS, SUPPORTED_BRIDGE_THING_TYPES_UIDS)
|
||||
.flatMap(Set::stream).collect(Collectors.toSet()));
|
||||
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Stream.of(SUPPORTED_LIGHTING_THING_TYPES,
|
||||
SUPPORTED_BUTTON_THING_TYPES_UIDS, SUPPORTED_HEATING_THING_TYPES, SUPPORTED_DEVICE_THING_TYPES_UIDS,
|
||||
SUPPORTED_GROUP_THING_TYPES_UIDS, SUPPORTED_BRIDGE_THING_TYPES_UIDS).flatMap(Set::stream)
|
||||
.collect(Collectors.toUnmodifiableSet());
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.openhab.binding.avmfritz.internal.handler.AVMFritzButtonHandler;
|
||||
import org.openhab.binding.avmfritz.internal.handler.AVMFritzColorLightDeviceHandler;
|
||||
import org.openhab.binding.avmfritz.internal.handler.AVMFritzHeatingDeviceHandler;
|
||||
import org.openhab.binding.avmfritz.internal.handler.AVMFritzHeatingGroupHandler;
|
||||
import org.openhab.binding.avmfritz.internal.handler.BoxHandler;
|
||||
@ -76,6 +77,8 @@ public class AVMFritzHandlerFactory extends BaseThingHandlerFactory {
|
||||
return new BoxHandler((Bridge) thing, httpClient, commandDescriptionProvider);
|
||||
} else if (PL546E_STANDALONE_THING_TYPE.equals(thingTypeUID)) {
|
||||
return new Powerline546EHandler((Bridge) thing, httpClient, commandDescriptionProvider);
|
||||
} else if (SUPPORTED_LIGHTING_THING_TYPES.contains(thingTypeUID)) {
|
||||
return new AVMFritzColorLightDeviceHandler(thing);
|
||||
} else if (SUPPORTED_BUTTON_THING_TYPES_UIDS.contains(thingTypeUID)) {
|
||||
return new AVMFritzButtonHandler(thing);
|
||||
} else if (SUPPORTED_HEATING_THING_TYPES.contains(thingTypeUID)) {
|
||||
|
@ -15,7 +15,6 @@ package org.openhab.binding.avmfritz.internal.discovery;
|
||||
import static org.openhab.binding.avmfritz.internal.AVMFritzBindingConstants.*;
|
||||
import static org.openhab.core.thing.Thing.*;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@ -56,12 +55,10 @@ public class AVMFritzDiscoveryService extends AbstractDiscoveryService
|
||||
private @NonNullByDefault({}) AVMFritzBaseBridgeHandler bridgeHandler;
|
||||
|
||||
public AVMFritzDiscoveryService() {
|
||||
super(Collections
|
||||
.unmodifiableSet(Stream
|
||||
.of(SUPPORTED_BUTTON_THING_TYPES_UIDS, SUPPORTED_HEATING_THING_TYPES,
|
||||
super(Stream
|
||||
.of(SUPPORTED_LIGHTING_THING_TYPES, SUPPORTED_BUTTON_THING_TYPES_UIDS, SUPPORTED_HEATING_THING_TYPES,
|
||||
SUPPORTED_DEVICE_THING_TYPES_UIDS, SUPPORTED_GROUP_THING_TYPES_UIDS)
|
||||
.flatMap(Set::stream).collect(Collectors.toSet())),
|
||||
30);
|
||||
.flatMap(Set::stream).collect(Collectors.toUnmodifiableSet()), 30);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -26,6 +26,7 @@ import org.eclipse.jdt.annotation.Nullable;
|
||||
*
|
||||
* <ol>
|
||||
* <li>Bit 0: HAN-FUN Gerät</li>
|
||||
* <li>Bit 2: Licht/Lampe</li>
|
||||
* <li>Bit 3: HAN-FUN Button - undocumented</li>
|
||||
* <li>Bit 4: Alarm-Sensor</li>
|
||||
* <li>Bit 5: AVM-Button</li>
|
||||
@ -37,6 +38,8 @@ import org.eclipse.jdt.annotation.Nullable;
|
||||
* <li>Bit 11: Mikrofon</li>
|
||||
* <li>Bit 13: HAN-FUN Unit</li>
|
||||
* <li>Bit 15: an-/ausschaltbares Gerät / Steckdose / Lampe / Aktor</li>
|
||||
* <li>Bit 16: Gerät mit einstellbarem Dimm-, Höhen- bzw. Niveau-Level</li>
|
||||
* <li>Bit 17: Lampe mit einstellbarer Farbe/Farbtemperatur</li>
|
||||
* <li>Bit 18: Rollladen - hoch, runter, stop und level 0% bis 100 %</li>
|
||||
* </ol>
|
||||
*
|
||||
@ -47,6 +50,7 @@ import org.eclipse.jdt.annotation.Nullable;
|
||||
*/
|
||||
public abstract class AVMFritzBaseModel implements BatteryModel {
|
||||
protected static final int HAN_FUN_DEVICE_BIT = 1; // Bit 0
|
||||
protected static final int LIGHT_BIT = 1 << 2; // Bit 2
|
||||
protected static final int HAN_FUN_BUTTON_BIT = 1 << 3; // Bit 3 - undocumented
|
||||
protected static final int HAN_FUN_ALARM_SENSOR_BIT = 1 << 4; // Bit 4
|
||||
protected static final int BUTTON_BIT = 1 << 5; // Bit 5
|
||||
@ -58,6 +62,8 @@ public abstract class AVMFritzBaseModel implements BatteryModel {
|
||||
protected static final int MICROPHONE_BIT = 1 << 11; // Bit 11
|
||||
protected static final int HAN_FUN_UNIT_BIT = 1 << 13; // Bit 13
|
||||
protected static final int HAN_FUN_ON_OFF_BIT = 1 << 15; // Bit 15
|
||||
protected static final int DIMMABLE_LIGHT_BIT = 1 << 16; // Bit 16
|
||||
protected static final int COLOR_LIGHT_BIT = 1 << 17; // Bit 17
|
||||
protected static final int HAN_FUN_BLINDS_BIT = 1 << 18; // Bit 18
|
||||
protected static final int HUMIDITY_SENSOR_BIT = 1 << 20; // Bit 20 - undocumented
|
||||
|
||||
@ -195,6 +201,14 @@ public abstract class AVMFritzBaseModel implements BatteryModel {
|
||||
return (bitmask / HAN_FUN_ON_OFF_BIT) > 0;
|
||||
}
|
||||
|
||||
public boolean isDimmableLight() {
|
||||
return (bitmask & DIMMABLE_LIGHT_BIT) > 0;
|
||||
}
|
||||
|
||||
public boolean isColorLight() {
|
||||
return (bitmask & COLOR_LIGHT_BIT) > 0;
|
||||
}
|
||||
|
||||
public boolean isHANFUNBlinds() {
|
||||
return (bitmask & HAN_FUN_BLINDS_BIT) > 0;
|
||||
}
|
||||
@ -239,7 +253,8 @@ public abstract class AVMFritzBaseModel implements BatteryModel {
|
||||
.append(",isPowermeter=").append(isPowermeter()).append(",isDectRepeater=").append(isDectRepeater())
|
||||
.append(",isHeatingThermostat=").append(isHeatingThermostat()).append(",hasMicrophone=")
|
||||
.append(hasMicrophone()).append(",isHANFUNUnit=").append(isHANFUNUnit()).append(",isHANFUNOnOff=")
|
||||
.append(isHANFUNOnOff()).append(",isHANFUNBlind=").append(isHANFUNBlinds()).append(",id=")
|
||||
.append(isHANFUNOnOff()).append(",isDimmableLight=").append(isDimmableLight()).append(",isColorLight=")
|
||||
.append(isColorLight()).append(",isHANFUNBlind=").append(isHANFUNBlinds()).append(",id=")
|
||||
.append(deviceId).append(",manufacturer=").append(deviceManufacturer).append(",productname=")
|
||||
.append(productName).append(",fwversion=").append(firmwareVersion).append(",present=").append(present)
|
||||
.append(",name=").append(name).append(",battery=").append(getBattery()).append(",batterylow=")
|
||||
|
@ -0,0 +1,43 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.avmfritz.internal.dto;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
/**
|
||||
* See {@link DeviceListModel}.
|
||||
*
|
||||
* @author Joshua Bacher - Initial contribution
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlRootElement(name = "colorcontrol")
|
||||
public class ColorControlModel {
|
||||
|
||||
@XmlAttribute(name = "supported_modes")
|
||||
public int supportedModes;
|
||||
@XmlAttribute(name = "current_mode")
|
||||
public int currentMode;
|
||||
public int hue;
|
||||
public int saturation;
|
||||
public int temperature;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new StringBuilder("[supportedModes=").append(supportedModes).append(",currentMode=").append(currentMode)
|
||||
.append(",hue=").append(hue).append(",saturation=").append(saturation).append(",temperature=")
|
||||
.append(temperature).append("]").toString();
|
||||
}
|
||||
}
|
@ -33,7 +33,12 @@ public class DeviceModel extends AVMFritzBaseModel {
|
||||
private TemperatureModel temperature;
|
||||
private HumidityModel humidity;
|
||||
private AlertModel alert;
|
||||
private LevelcontrolModel levelcontrol;
|
||||
|
||||
@XmlElement(name = "levelcontrol")
|
||||
private LevelControlModel levelControlModel;
|
||||
|
||||
@XmlElement(name = "colorcontrol")
|
||||
private ColorControlModel colorControlModel;
|
||||
|
||||
@XmlElement(name = "button", type = ButtonModel.class)
|
||||
private List<ButtonModel> buttons;
|
||||
@ -64,12 +69,20 @@ public class DeviceModel extends AVMFritzBaseModel {
|
||||
this.alert = alertModel;
|
||||
}
|
||||
|
||||
public LevelcontrolModel getLevelcontrol() {
|
||||
return levelcontrol;
|
||||
public LevelControlModel getLevelControlModel() {
|
||||
return levelControlModel;
|
||||
}
|
||||
|
||||
public void setLevelcontrol(LevelcontrolModel levelcontrol) {
|
||||
this.levelcontrol = levelcontrol;
|
||||
public void setLevelControlModel(LevelControlModel levelControlModel) {
|
||||
this.levelControlModel = levelControlModel;
|
||||
}
|
||||
|
||||
public ColorControlModel getColorControlModel() {
|
||||
return colorControlModel;
|
||||
}
|
||||
|
||||
public void setColorControlModel(ColorControlModel colorControlModel) {
|
||||
this.colorControlModel = colorControlModel;
|
||||
}
|
||||
|
||||
public List<ButtonModel> getButtons() {
|
||||
@ -91,7 +104,8 @@ public class DeviceModel extends AVMFritzBaseModel {
|
||||
@Override
|
||||
public String toString() {
|
||||
return new StringBuilder(super.toString()).append(temperature).append(",").append(humidity).append(",")
|
||||
.append(alert).append(",").append(getButtons()).append(",").append(etsiunitinfo).append("]").toString();
|
||||
.append(alert).append(",").append(levelControlModel).append(",").append(colorControlModel).append(",")
|
||||
.append(getButtons()).append(",").append(etsiunitinfo).append("]").toString();
|
||||
}
|
||||
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
|
@ -26,7 +26,7 @@ import javax.xml.bind.annotation.XmlRootElement;
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlRootElement(name = "levelcontrol")
|
||||
public class LevelcontrolModel {
|
||||
public class LevelControlModel {
|
||||
|
||||
@XmlElement(name = "level")
|
||||
private BigDecimal level;
|
||||
@ -52,7 +52,7 @@ public class LevelcontrolModel {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new StringBuilder().append("[level=").append(getLevel()).append(",levelpercentage=")
|
||||
.append(getLevelPercentage()).append("]").toString();
|
||||
return new StringBuilder("[level=").append(getLevel()).append(",levelpercentage=").append(getLevelPercentage())
|
||||
.append("]").toString();
|
||||
}
|
||||
}
|
@ -29,11 +29,12 @@ import org.openhab.binding.avmfritz.internal.config.AVMFritzDeviceConfiguration;
|
||||
import org.openhab.binding.avmfritz.internal.dto.AVMFritzBaseModel;
|
||||
import org.openhab.binding.avmfritz.internal.dto.AlertModel;
|
||||
import org.openhab.binding.avmfritz.internal.dto.BatteryModel;
|
||||
import org.openhab.binding.avmfritz.internal.dto.ColorControlModel;
|
||||
import org.openhab.binding.avmfritz.internal.dto.DeviceModel;
|
||||
import org.openhab.binding.avmfritz.internal.dto.HeatingModel;
|
||||
import org.openhab.binding.avmfritz.internal.dto.HeatingModel.NextChangeModel;
|
||||
import org.openhab.binding.avmfritz.internal.dto.HumidityModel;
|
||||
import org.openhab.binding.avmfritz.internal.dto.LevelcontrolModel;
|
||||
import org.openhab.binding.avmfritz.internal.dto.LevelControlModel;
|
||||
import org.openhab.binding.avmfritz.internal.dto.PowerMeterModel;
|
||||
import org.openhab.binding.avmfritz.internal.dto.SimpleOnOffModel;
|
||||
import org.openhab.binding.avmfritz.internal.dto.SwitchModel;
|
||||
@ -44,6 +45,7 @@ import org.openhab.binding.avmfritz.internal.hardware.callbacks.FritzAhaSetBlind
|
||||
import org.openhab.core.config.core.Configuration;
|
||||
import org.openhab.core.library.types.DateTimeType;
|
||||
import org.openhab.core.library.types.DecimalType;
|
||||
import org.openhab.core.library.types.HSBType;
|
||||
import org.openhab.core.library.types.IncreaseDecreaseType;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.library.types.OpenClosedType;
|
||||
@ -156,7 +158,12 @@ public abstract class AVMFritzBaseThingHandler extends BaseThingHandler implemen
|
||||
updateHANFUNAlarmSensor(deviceModel.getAlert());
|
||||
}
|
||||
if (deviceModel.isHANFUNBlinds()) {
|
||||
updateLevelcontrol(deviceModel.getLevelcontrol());
|
||||
updateLevelControl(deviceModel.getLevelControlModel());
|
||||
}
|
||||
if (deviceModel.isColorLight()) {
|
||||
updateColorLight(deviceModel.getColorControlModel(), deviceModel.getLevelControlModel());
|
||||
} else if (deviceModel.isDimmableLight()) {
|
||||
updateDimmableLight(deviceModel.getLevelControlModel());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -185,9 +192,26 @@ public abstract class AVMFritzBaseThingHandler extends BaseThingHandler implemen
|
||||
}
|
||||
}
|
||||
|
||||
protected void updateLevelcontrol(@Nullable LevelcontrolModel levelcontrolModel) {
|
||||
if (levelcontrolModel != null) {
|
||||
updateThingChannelState(CHANNEL_ROLLERSHUTTER, new PercentType(levelcontrolModel.getLevelPercentage()));
|
||||
protected void updateLevelControl(@Nullable LevelControlModel levelControlModel) {
|
||||
if (levelControlModel != null) {
|
||||
updateThingChannelState(CHANNEL_ROLLERSHUTTER, new PercentType(levelControlModel.getLevelPercentage()));
|
||||
}
|
||||
}
|
||||
|
||||
private void updateDimmableLight(@Nullable LevelControlModel levelControlModel) {
|
||||
if (levelControlModel != null) {
|
||||
updateThingChannelState(CHANNEL_BRIGHTNESS, new PercentType(levelControlModel.getLevelPercentage()));
|
||||
}
|
||||
}
|
||||
|
||||
private void updateColorLight(@Nullable ColorControlModel colorControlModel,
|
||||
@Nullable LevelControlModel levelControlModel) {
|
||||
if (colorControlModel != null && levelControlModel != null) {
|
||||
DecimalType hue = new DecimalType(colorControlModel.hue);
|
||||
PercentType saturation = new PercentType(colorControlModel.saturation);
|
||||
PercentType brightness = new PercentType(levelControlModel.getLevelPercentage());
|
||||
updateThingChannelState(CHANNEL_COLOR, new HSBType(hue, saturation, brightness));
|
||||
updateThingChannelState(CHANNEL_BRIGHTNESS, brightness);
|
||||
}
|
||||
}
|
||||
|
||||
@ -384,6 +408,21 @@ public abstract class AVMFritzBaseThingHandler extends BaseThingHandler implemen
|
||||
fritzBox.setSwitch(ain, OnOffType.ON.equals(command));
|
||||
}
|
||||
break;
|
||||
case CHANNEL_COLOR:
|
||||
case CHANNEL_BRIGHTNESS:
|
||||
BigDecimal brightness = null;
|
||||
if (command instanceof HSBType) {
|
||||
HSBType hsbType = (HSBType) command;
|
||||
brightness = hsbType.getBrightness().toBigDecimal();
|
||||
fritzBox.setHueAndSaturation(ain, hsbType.getHue().intValue(), hsbType.getSaturation().intValue(),
|
||||
0);
|
||||
} else if (command instanceof PercentType) {
|
||||
brightness = ((PercentType) command).toBigDecimal();
|
||||
}
|
||||
if (brightness != null) {
|
||||
fritzBox.setLevelPercentage(ain, brightness);
|
||||
}
|
||||
break;
|
||||
case CHANNEL_SETTEMP:
|
||||
BigDecimal temperature = null;
|
||||
if (command instanceof DecimalType) {
|
||||
@ -462,9 +501,8 @@ public abstract class AVMFritzBaseThingHandler extends BaseThingHandler implemen
|
||||
fritzBox.setBlind(ain, BlindCommand.CLOSE);
|
||||
}
|
||||
} else if (command instanceof PercentType) {
|
||||
PercentType rollershutterCommand = (PercentType) command;
|
||||
BigDecimal levelpercentage = rollershutterCommand.toBigDecimal();
|
||||
fritzBox.setLevelpercentage(ain, levelpercentage);
|
||||
BigDecimal levelPercentage = ((PercentType) command).toBigDecimal();
|
||||
fritzBox.setLevelPercentage(ain, levelPercentage);
|
||||
} else {
|
||||
logger.debug("Received unknown rollershutter command type '{}'", command.toString());
|
||||
}
|
||||
|
@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.avmfritz.internal.handler;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.thing.Thing;
|
||||
|
||||
/**
|
||||
* Handler for a FRITZ! color light device. Handles commands, which are sent to one of the channels.
|
||||
*
|
||||
* @author Joshua Bacher - Initial contribution
|
||||
* @author Christoph Weitkamp - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class AVMFritzColorLightDeviceHandler extends DeviceHandler {
|
||||
|
||||
public AVMFritzColorLightDeviceHandler(Thing thing) {
|
||||
super(thing);
|
||||
}
|
||||
}
|
@ -56,13 +56,14 @@ public class FritzAhaContentExchange extends BufferingResponseListener
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNullByDefault({}) Response response, @NonNullByDefault({}) Throwable failure) {
|
||||
logger.debug("response failed: {}", failure.getLocalizedMessage(), failure);
|
||||
logger.debug("{} response failed: {}", response.getRequest().getMethod(), failure.getLocalizedMessage(),
|
||||
failure);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete(@NonNullByDefault({}) Result result) {
|
||||
String content = getContentAsString();
|
||||
logger.debug("response complete: {}", content);
|
||||
logger.debug("{} response complete: {}", result.getRequest().getMethod(), content);
|
||||
callback.execute(result.getResponse().getStatus(), content);
|
||||
}
|
||||
}
|
||||
|
@ -12,8 +12,6 @@
|
||||
*/
|
||||
package org.openhab.binding.avmfritz.internal.hardware;
|
||||
|
||||
import static org.eclipse.jetty.http.HttpMethod.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.MessageDigest;
|
||||
@ -29,15 +27,17 @@ import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.api.ContentResponse;
|
||||
import org.eclipse.jetty.client.util.StringContentProvider;
|
||||
import org.eclipse.jetty.http.HttpMethod;
|
||||
import org.openhab.binding.avmfritz.internal.config.AVMFritzBoxConfiguration;
|
||||
import org.openhab.binding.avmfritz.internal.handler.AVMFritzBaseBridgeHandler;
|
||||
import org.openhab.binding.avmfritz.internal.hardware.callbacks.FritzAhaApplyTemplateCallback;
|
||||
import org.openhab.binding.avmfritz.internal.hardware.callbacks.FritzAhaCallback;
|
||||
import org.openhab.binding.avmfritz.internal.hardware.callbacks.FritzAhaSetBlindLevelCallback;
|
||||
import org.openhab.binding.avmfritz.internal.hardware.callbacks.FritzAhaSetBlindTargetCallback;
|
||||
import org.openhab.binding.avmfritz.internal.hardware.callbacks.FritzAhaSetBlindTargetCallback.BlindCommand;
|
||||
import org.openhab.binding.avmfritz.internal.hardware.callbacks.FritzAhaSetColorCallback;
|
||||
import org.openhab.binding.avmfritz.internal.hardware.callbacks.FritzAhaSetHeatingModeCallback;
|
||||
import org.openhab.binding.avmfritz.internal.hardware.callbacks.FritzAhaSetHeatingTemperatureCallback;
|
||||
import org.openhab.binding.avmfritz.internal.hardware.callbacks.FritzAhaSetLevelPercentageCallback;
|
||||
import org.openhab.binding.avmfritz.internal.hardware.callbacks.FritzAhaSetSwitchCallback;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
@ -239,18 +239,18 @@ public class FritzAhaWebInterface {
|
||||
* @param path Path of the requested resource
|
||||
* @return response
|
||||
*/
|
||||
public @Nullable String syncGet(String url) {
|
||||
public @Nullable String syncGet(String path) {
|
||||
try {
|
||||
ContentResponse contentResponse = httpClient.newRequest(url)
|
||||
.timeout(config.syncTimeout, TimeUnit.MILLISECONDS).method(GET).send();
|
||||
ContentResponse contentResponse = httpClient.newRequest(path)
|
||||
.timeout(config.syncTimeout, TimeUnit.MILLISECONDS).method(HttpMethod.GET).send();
|
||||
String content = contentResponse.getContentAsString();
|
||||
logger.debug("GET response complete: {}", content);
|
||||
return content;
|
||||
} catch (ExecutionException | TimeoutException e) {
|
||||
logger.debug("response failed: {}", e.getLocalizedMessage(), e);
|
||||
logger.debug("GET response failed: {}", e.getLocalizedMessage(), e);
|
||||
return null;
|
||||
} catch (InterruptedException e) {
|
||||
logger.debug("response interrupted: {}", e.getLocalizedMessage(), e);
|
||||
logger.debug("GET response interrupted: {}", e.getLocalizedMessage(), e);
|
||||
Thread.currentThread().interrupt();
|
||||
return null;
|
||||
}
|
||||
@ -268,7 +268,7 @@ public class FritzAhaWebInterface {
|
||||
authenticate();
|
||||
}
|
||||
FritzAhaContentExchange getExchange = new FritzAhaContentExchange(callback);
|
||||
httpClient.newRequest(getURL(path, addSID(args))).method(GET).onResponseSuccess(getExchange)
|
||||
httpClient.newRequest(getURL(path, addSID(args))).method(HttpMethod.GET).onResponseSuccess(getExchange)
|
||||
.onResponseFailure(getExchange).send(getExchange);
|
||||
return getExchange;
|
||||
}
|
||||
@ -289,7 +289,7 @@ public class FritzAhaWebInterface {
|
||||
authenticate();
|
||||
}
|
||||
FritzAhaContentExchange postExchange = new FritzAhaContentExchange(callback);
|
||||
httpClient.newRequest(getURL(path)).timeout(config.asyncTimeout, TimeUnit.MILLISECONDS).method(POST)
|
||||
httpClient.newRequest(getURL(path)).timeout(config.asyncTimeout, TimeUnit.MILLISECONDS).method(HttpMethod.POST)
|
||||
.onResponseSuccess(postExchange).onResponseFailure(postExchange)
|
||||
.content(new StringContentProvider(addSID(args), StandardCharsets.UTF_8)).send(postExchange);
|
||||
return postExchange;
|
||||
@ -324,8 +324,14 @@ public class FritzAhaWebInterface {
|
||||
return asyncGet(callback);
|
||||
}
|
||||
|
||||
public FritzAhaContentExchange setLevelpercentage(String ain, BigDecimal levelpercentage) {
|
||||
FritzAhaSetBlindLevelCallback callback = new FritzAhaSetBlindLevelCallback(this, ain, levelpercentage);
|
||||
public FritzAhaContentExchange setLevelPercentage(String ain, BigDecimal levelPercentage) {
|
||||
FritzAhaSetLevelPercentageCallback callback = new FritzAhaSetLevelPercentageCallback(this, ain,
|
||||
levelPercentage);
|
||||
return asyncGet(callback);
|
||||
}
|
||||
|
||||
public FritzAhaContentExchange setHueAndSaturation(String ain, int hue, int saturation, int duration) {
|
||||
FritzAhaSetColorCallback callback = new FritzAhaSetColorCallback(this, ain, hue, saturation, duration);
|
||||
return asyncGet(callback);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,57 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.avmfritz.internal.hardware.callbacks;
|
||||
|
||||
import static org.eclipse.jetty.http.HttpMethod.GET;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.avmfritz.internal.hardware.FritzAhaWebInterface;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Callback implementation for updating hue, saturation and duration. Supports reauthorization
|
||||
*
|
||||
* @author Christoph Weitkamp - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class FritzAhaSetColorCallback extends FritzAhaReauthCallback {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(FritzAhaSetColorCallback.class);
|
||||
|
||||
private final String ain;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param webIface Interface to FRITZ!Box
|
||||
* @param ain AIN of the device that should be switched
|
||||
* @param hue New hue
|
||||
* @param saturation New saturation
|
||||
* @param duration Duration of the change in 100ms. 0 immediately.
|
||||
*/
|
||||
public FritzAhaSetColorCallback(FritzAhaWebInterface webIface, String ain, int hue, int saturation, int duration) {
|
||||
super(WEBSERVICE_PATH,
|
||||
"switchcmd=setcolor&ain=" + ain + "&hue=" + hue + "&saturation=" + saturation + "&duration=" + duration,
|
||||
webIface, GET, 1);
|
||||
this.ain = ain;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(int status, String response) {
|
||||
super.execute(status, response);
|
||||
if (isValidRequest()) {
|
||||
logger.debug("Received response '{}' for item '{}'", response, ain);
|
||||
}
|
||||
}
|
||||
}
|
@ -22,14 +22,14 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Callback implementation for updating blind commands. Supports reauthorization
|
||||
* Callback implementation for updating blind / levelpercentage commands. Supports reauthorization
|
||||
*
|
||||
* @author Ulrich Mertin - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class FritzAhaSetBlindLevelCallback extends FritzAhaReauthCallback {
|
||||
public class FritzAhaSetLevelPercentageCallback extends FritzAhaReauthCallback {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(FritzAhaSetBlindLevelCallback.class);
|
||||
private final Logger logger = LoggerFactory.getLogger(FritzAhaSetLevelPercentageCallback.class);
|
||||
|
||||
private final String ain;
|
||||
|
||||
@ -40,8 +40,8 @@ public class FritzAhaSetBlindLevelCallback extends FritzAhaReauthCallback {
|
||||
* @param ain AIN of the device that should be switched
|
||||
* @param level Opening level percentage (0 ... 100)
|
||||
*/
|
||||
public FritzAhaSetBlindLevelCallback(FritzAhaWebInterface webIface, String ain, BigDecimal levelpercentage) {
|
||||
super(WEBSERVICE_PATH, "switchcmd=setlevelpercentage&level=" + levelpercentage + "&ain=" + ain, webIface, GET,
|
||||
public FritzAhaSetLevelPercentageCallback(FritzAhaWebInterface webIface, String ain, BigDecimal levelPercentage) {
|
||||
super(WEBSERVICE_PATH, "switchcmd=setlevelpercentage&level=" + levelPercentage + "&ain=" + ain, webIface, GET,
|
||||
1);
|
||||
this.ain = ain;
|
||||
}
|
@ -5,6 +5,25 @@
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<!-- Supported FRITZ! devices and features -->
|
||||
<thing-type id="FRITZ_DECT_500">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="fritzbox"/>
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>FRITZ!DECT 500</label>
|
||||
<description>FRITZ!DECT500 color light.</description>
|
||||
|
||||
<channels>
|
||||
<channel id="onoffstate" typeId="system.power"/>
|
||||
<channel id="brightness" typeId="system.brightness"/>
|
||||
<channel id="color" typeId="system.color"/>
|
||||
</channels>
|
||||
|
||||
<representation-property>ain</representation-property>
|
||||
|
||||
<config-description-ref uri="thing-type:avmfritz:fritzdevice"/>
|
||||
</thing-type>
|
||||
|
||||
<thing-type id="FRITZ_DECT_400">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="fritzbox"/>
|
||||
|
@ -137,7 +137,7 @@ public class AVMFritzDeviceListModelTest {
|
||||
|
||||
assertNull(device.getHkr());
|
||||
|
||||
assertNull(device.getLevelcontrol());
|
||||
assertNull(device.getLevelControlModel());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -184,7 +184,7 @@ public class AVMFritzDeviceListModelTest {
|
||||
|
||||
assertNull(device.getHkr());
|
||||
|
||||
assertNull(device.getLevelcontrol());
|
||||
assertNull(device.getLevelControlModel());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -231,7 +231,7 @@ public class AVMFritzDeviceListModelTest {
|
||||
|
||||
assertNull(device.getHkr());
|
||||
|
||||
assertNull(device.getLevelcontrol());
|
||||
assertNull(device.getLevelControlModel());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -394,7 +394,7 @@ public class AVMFritzDeviceListModelTest {
|
||||
|
||||
assertNull(device.getHkr());
|
||||
|
||||
assertNull(device.getLevelcontrol());
|
||||
assertNull(device.getLevelControlModel());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -464,7 +464,7 @@ public class AVMFritzDeviceListModelTest {
|
||||
|
||||
assertNull(device.getHkr());
|
||||
|
||||
assertNull(device.getLevelcontrol());
|
||||
assertNull(device.getLevelControlModel());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -506,7 +506,7 @@ public class AVMFritzDeviceListModelTest {
|
||||
|
||||
assertNull(device.getHkr());
|
||||
|
||||
assertNull(device.getLevelcontrol());
|
||||
assertNull(device.getLevelControlModel());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -549,7 +549,7 @@ public class AVMFritzDeviceListModelTest {
|
||||
|
||||
assertNull(device.getHkr());
|
||||
|
||||
assertNull(device.getLevelcontrol());
|
||||
assertNull(device.getLevelControlModel());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -592,7 +592,7 @@ public class AVMFritzDeviceListModelTest {
|
||||
|
||||
assertNull(device.getHkr());
|
||||
|
||||
assertNull(device.getLevelcontrol());
|
||||
assertNull(device.getLevelControlModel());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -635,7 +635,7 @@ public class AVMFritzDeviceListModelTest {
|
||||
|
||||
assertNull(device.getHkr());
|
||||
|
||||
LevelcontrolModel levelcontrol = device.getLevelcontrol();
|
||||
LevelControlModel levelcontrol = device.getLevelControlModel();
|
||||
assertNotNull(levelcontrol);
|
||||
assertEquals(BigDecimal.valueOf(26L), levelcontrol.getLevel());
|
||||
assertEquals(BigDecimal.valueOf(10L), levelcontrol.getLevelPercentage());
|
||||
@ -687,7 +687,7 @@ public class AVMFritzDeviceListModelTest {
|
||||
|
||||
assertNull(device.getHkr());
|
||||
|
||||
assertNull(device.getLevelcontrol());
|
||||
assertNull(device.getLevelControlModel());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -89,7 +89,7 @@ public class AVMFritzDiscoveryServiceOSGiTest extends AVMFritzThingHandlerOSGiTe
|
||||
|
||||
@Test
|
||||
public void correctSupportedTypes() {
|
||||
assertEquals(15, discovery.getSupportedThingTypes().size());
|
||||
assertEquals(16, discovery.getSupportedThingTypes().size());
|
||||
assertTrue(discovery.getSupportedThingTypes().contains(DECT100_THING_TYPE));
|
||||
assertTrue(discovery.getSupportedThingTypes().contains(DECT200_THING_TYPE));
|
||||
assertTrue(discovery.getSupportedThingTypes().contains(DECT210_THING_TYPE));
|
||||
@ -97,6 +97,7 @@ public class AVMFritzDiscoveryServiceOSGiTest extends AVMFritzThingHandlerOSGiTe
|
||||
assertTrue(discovery.getSupportedThingTypes().contains(DECT301_THING_TYPE));
|
||||
assertTrue(discovery.getSupportedThingTypes().contains(DECT400_THING_TYPE));
|
||||
assertTrue(discovery.getSupportedThingTypes().contains(DECT440_THING_TYPE));
|
||||
assertTrue(discovery.getSupportedThingTypes().contains(DECT500_THING_TYPE));
|
||||
assertTrue(discovery.getSupportedThingTypes().contains(PL546E_THING_TYPE));
|
||||
assertTrue(discovery.getSupportedThingTypes().contains(COMETDECT_THING_TYPE));
|
||||
assertTrue(discovery.getSupportedThingTypes().contains(HAN_FUN_CONTACT_THING_TYPE));
|
||||
|
Loading…
Reference in New Issue
Block a user