Skip to content

Commit

Permalink
[tapocontrol] color temperature channel improvements (openhab#17779)
Browse files Browse the repository at this point in the history
Signed-off-by: AndrewFG <[email protected]>
  • Loading branch information
andrewfg authored and matchews committed Dec 16, 2024
1 parent 20fde27 commit d77efd7
Show file tree
Hide file tree
Showing 11 changed files with 151 additions and 26 deletions.
2 changes: 1 addition & 1 deletion bundles/org.openhab.binding.tapocontrol/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ All devices support some of the following channels:
| | output2 | Switch | Power socket 2 on or off | P300 |
| | output3 | Switch | Power socket 3 on or off | P300 |
| | brightness | Dimmer | Brightness 0-100% | L510, L530, L610, L630, L900, L920 |
| | colorTemperature | Number | White-Color-Temp 2500-6500K | L510, L530, L610, L630, L900, L920 |
| | colorTemperature | Number:Temperature | Color Temperature in Kelvin | L530 (2500 K .. 6500 K), L630 (2200 K .. 6500 K) |
| | color | Color | Color | L530, L630, L900, L920 |
| sensor | isOpen | Switch | Contact (Door/Window) is Open | T110 |
| | currentTemp | Number:Temperature | Current Temperature | T310, T315 |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,12 @@ public class TapoControlHandlerFactory extends BaseThingHandlerFactory {
private final Logger logger = LoggerFactory.getLogger(TapoControlHandlerFactory.class);
private final Set<TapoBridgeHandler> accountHandlers = new HashSet<>();
private final HttpClient httpClient;
private final TapoStateDescriptionProvider stateDescriptionProvider;

@Activate
public TapoControlHandlerFactory(final @Reference HttpClientFactory httpClientFactory) {
public TapoControlHandlerFactory(final @Reference HttpClientFactory httpClientFactory,
final @Reference TapoStateDescriptionProvider tapoStateDescriptionProvider) {
this.stateDescriptionProvider = tapoStateDescriptionProvider;
// create new httpClient
httpClient = httpClientFactory.createHttpClient(BINDING_ID, new SslContextFactory.Client());
httpClient.setFollowRedirects(false);
Expand Down Expand Up @@ -118,9 +121,9 @@ public boolean supportsThingType(ThingTypeUID thingTypeUID) {
} else if (SUPPORTED_SOCKET_STRIP_UIDS.contains(thingTypeUID)) {
return new TapoSocketStripHandler(thing);
} else if (SUPPORTED_WHITE_BULB_UIDS.contains(thingTypeUID)) {
return new TapoBulbHandler(thing);
return new TapoBulbHandler(thing, stateDescriptionProvider);
} else if (SUPPORTED_COLOR_BULB_UIDS.contains(thingTypeUID)) {
return new TapoBulbHandler(thing);
return new TapoBulbHandler(thing, stateDescriptionProvider);
} else if (SUPPORTED_LIGHT_STRIP_UIDS.contains(thingTypeUID)) {
return new TapoLightStripHandler(thing);
} else if (SUPPORTED_SMART_CONTACTS.contains(thingTypeUID)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/**
* 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.tapocontrol.internal;

import java.math.BigDecimal;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.events.EventPublisher;
import org.openhab.core.thing.Channel;
import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.binding.BaseDynamicStateDescriptionProvider;
import org.openhab.core.thing.events.ThingEventFactory;
import org.openhab.core.thing.i18n.ChannelTypeI18nLocalizationService;
import org.openhab.core.thing.link.ItemChannelLinkRegistry;
import org.openhab.core.thing.type.DynamicStateDescriptionProvider;
import org.openhab.core.types.StateDescription;
import org.openhab.core.types.StateDescriptionFragment;
import org.openhab.core.types.StateDescriptionFragmentBuilder;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;

/**
* The {@link TapoStateDescriptionProvider} provides state descriptions for different color temperature light models.
*
* @author Andrew Fiddian-Green - Initial contribution
*
*/
@NonNullByDefault
@Component(service = { DynamicStateDescriptionProvider.class, TapoStateDescriptionProvider.class })
public class TapoStateDescriptionProvider extends BaseDynamicStateDescriptionProvider {

private final Map<ChannelUID, StateDescriptionFragment> stateDescriptionFragments = new ConcurrentHashMap<>();

@Activate
public TapoStateDescriptionProvider(final @Reference EventPublisher eventPublisher,
final @Reference ItemChannelLinkRegistry itemChannelLinkRegistry,
final @Reference ChannelTypeI18nLocalizationService channelTypeI18nLocalizationService) {
this.eventPublisher = eventPublisher;
this.itemChannelLinkRegistry = itemChannelLinkRegistry;
this.channelTypeI18nLocalizationService = channelTypeI18nLocalizationService;
}

@Override
public @Nullable StateDescription getStateDescription(Channel channel, @Nullable StateDescription original,
@Nullable Locale locale) {
StateDescriptionFragment stateDescriptionFragment = stateDescriptionFragments.get(channel.getUID());
return stateDescriptionFragment != null ? stateDescriptionFragment.toStateDescription()
: super.getStateDescription(channel, original, locale);
}

/**
* Set the state description minimum and maximum values and pattern in Kelvin for the given channel UID
*/
public void setMinMaxKelvin(ChannelUID channelUID, long minKelvin, long maxKelvin) {
StateDescriptionFragment oldStateDescriptionFragment = stateDescriptionFragments.get(channelUID);
StateDescriptionFragment newStateDescriptionFragment = StateDescriptionFragmentBuilder.create()
.withMinimum(BigDecimal.valueOf(minKelvin)).withMaximum(BigDecimal.valueOf(maxKelvin))
.withStep(BigDecimal.valueOf(100)).withPattern("%.0f K").build();
if (!newStateDescriptionFragment.equals(oldStateDescriptionFragment)) {
stateDescriptionFragments.put(channelUID, newStateDescriptionFragment);
ItemChannelLinkRegistry itemChannelLinkRegistry = this.itemChannelLinkRegistry;
postEvent(ThingEventFactory.createChannelDescriptionChangedEvent(channelUID,
itemChannelLinkRegistry != null ? itemChannelLinkRegistry.getLinkedItemNames(channelUID) : Set.of(),
newStateDescriptionFragment, oldStateDescriptionFragment));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ public class TapoThingConstants {
public static final String CHILD_REPRESENTATION_PROPERTY = "serialNumber";

/*** DEVICE SETTINGS ***/
public static final Integer BULB_MIN_COLORTEMP_EXT = 2200;
public static final Integer BULB_MIN_COLORTEMP = 2500;
public static final Integer BULB_MAX_COLORTEMP = 6500;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import static org.openhab.binding.tapocontrol.internal.helpers.utils.TypeUtils.*;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.binding.tapocontrol.internal.TapoStateDescriptionProvider;
import org.openhab.binding.tapocontrol.internal.devices.dto.TapoLightDynamicFx;
import org.openhab.binding.tapocontrol.internal.devices.wifi.TapoBaseDeviceHandler;
import org.openhab.binding.tapocontrol.internal.helpers.TapoErrorHandler;
Expand All @@ -25,8 +26,10 @@
import org.openhab.core.library.types.OnOffType;
import org.openhab.core.library.types.PercentType;
import org.openhab.core.library.unit.Units;
import org.openhab.core.thing.ChannelGroupUID;
import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingTypeUID;
import org.openhab.core.types.Command;
import org.openhab.core.types.RefreshType;
import org.slf4j.Logger;
Expand All @@ -42,20 +45,34 @@ public class TapoBulbHandler extends TapoBaseDeviceHandler {
private final Logger logger = LoggerFactory.getLogger(TapoBulbHandler.class);
private TapoBulbData bulbData = new TapoBulbData();
private TapoBulbLastStates lastStates = new TapoBulbLastStates();
private final TapoStateDescriptionProvider stateDescriptionProvider;

/**
* Constructor
*
*
* @param thing Thing object representing device
*/
public TapoBulbHandler(Thing thing) {
public TapoBulbHandler(Thing thing, TapoStateDescriptionProvider stateDescriptionProvider) {
super(thing);
this.stateDescriptionProvider = stateDescriptionProvider;
}

@Override
public void initialize() {
super.initialize();
ThingTypeUID typeUID = thing.getThingTypeUID();
if (SUPPORTED_COLOR_BULB_UIDS.contains(typeUID)) {
ChannelGroupUID groupUID = new ChannelGroupUID(getThingUID(), CHANNEL_GROUP_ACTUATOR);
ChannelUID channnelUID = new ChannelUID(groupUID, CHANNEL_COLOR_TEMP);
long minKelvin = L630_THING_TYPE.equals(typeUID) ? BULB_MIN_COLORTEMP_EXT : BULB_MIN_COLORTEMP;
stateDescriptionProvider.setMinMaxKelvin(channnelUID, minKelvin, BULB_MAX_COLORTEMP);
}
}

/**
* Function called by {@link org.openhab.binding.tapocontrol.internal.api.TapoDeviceConnector} if new data were
* received
*
*
* @param queryCommand command where new data belong to
*/
@Override
Expand All @@ -74,7 +91,7 @@ public void newDataResult(String queryCommand) {

/**
* handle command sent to device
*
*
* @param channelUID channelUID command is sent to
* @param command command to be sent
*/
Expand Down Expand Up @@ -149,7 +166,7 @@ private void handleModeChange(Command command) {

/**
* Switch device On or Off
*
*
* @param on if true device will switch on. Otherwise switch off
*/
protected void switchOnOff(boolean on) {
Expand All @@ -159,7 +176,7 @@ protected void switchOnOff(boolean on) {

/**
* Set Britghtness of device
*
*
* @param newBrightness percentage 0-100 of new brightness
*/
protected void setBrightness(Integer newBrightness) {
Expand All @@ -175,7 +192,7 @@ protected void setBrightness(Integer newBrightness) {

/**
* Set Color of Device
*
*
* @param command HSBType
*/
protected void setColor(HSBType command) {
Expand All @@ -189,7 +206,7 @@ protected void setColor(HSBType command) {

/**
* Set ColorTemp
*
*
* @param colorTemp (Integer) in Kelvin
*/
protected void setColorTemp(Integer colorTemp) {
Expand All @@ -201,7 +218,7 @@ protected void setColorTemp(Integer colorTemp) {

/**
* Set light effect
*
*
* @param fxId (String) id of LightEffect
*/
protected void setLightEffect(String fxId) {
Expand All @@ -216,7 +233,7 @@ protected void setLightEffect(String fxId) {

/**
* Set last state by mode
*
*
* @param mode mode to set
*/
protected void setLastMode(TapoBulbModeEnum mode) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,6 @@ channel-type.tapocontrol.colorBulbMode.command.option.COLOR_LIGHT = Color
channel-type.tapocontrol.colorBulbMode.command.option.LIGHT_FX = Effects
channel-type.tapocontrol.colorChannel.label = Color
channel-type.tapocontrol.colorChannel.description = Color
channel-type.tapocontrol.colorTemperature.label = Color Temperature
channel-type.tapocontrol.colorTemperature.description = This channel supports adjusting the color temperature from 2200K to 6500K.
channel-type.tapocontrol.contactCloseEvent.label = Contact Closed
channel-type.tapocontrol.contactCloseEvent.description = Event is fired if contact changes from open to closed
channel-type.tapocontrol.contactOpenEvent.label = Contact Opened
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@
<channel-group id="effects" typeId="lightEffectL530"/>
<channel-group id="device" typeId="deviceState"/>
</channel-groups>

<properties>
<property name="thingTypeVersion">1</property>
</properties>

<representation-property>macAddress</representation-property>

<config-description-ref uri="thing-type:tapo:device"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@
<channel-group id="actuator" typeId="colorBulb"/>
<channel-group id="device" typeId="deviceStateS"/>
</channel-groups>

<properties>
<property name="thingTypeVersion">1</property>
</properties>

<representation-property>macAddress</representation-property>

<config-description-ref uri="thing-type:tapo:device"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@
<channel id="mode" typeId="colorBulbMode"/>
<channel id="brightness" typeId="dimmerChannel"/>
<channel id="color" typeId="colorChannel"/>
<channel id="colorTemperature" typeId="colorTemperature"/>
<channel id="colorTemperature" typeId="system.color-temperature-abs"/>
</channels>
</channel-group-type>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,6 @@
<state readOnly="false"/>
</channel-type>

<!-- Color Temperature -->
<channel-type id="colorTemperature">
<item-type>Number</item-type>
<label>Color Temperature</label>
<description>This channel supports adjusting the color temperature from 2200K to 6500K.</description>
<category>LightBulb</category>
<state min="2200" max="6500" pattern="%d K"/>
</channel-type>

<!-- SENSOR CHANNEL TYPES -->
<!-- SmartContact "isOpen" Channel Type -->
<channel-type id="isOpenChannel">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<update:update-descriptions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:update="https://openhab.org/schemas/update-description/v1.0.0"
xsi:schemaLocation="https://openhab.org/schemas/update-description/v1.0.0 https://openhab.org/schemas/update-description-1.0.0.xsd">

<thing-type uid="tapocontrol:L530">
<instruction-set targetVersion="1">
<update-channel id="colorTemperature">
<type>system:color-temperature-abs</type>
</update-channel>
</instruction-set>
</thing-type>

<thing-type uid="tapocontrol:L630">
<instruction-set targetVersion="1">
<update-channel id="colorTemperature">
<type>system:color-temperature-abs</type>
</update-channel>
</instruction-set>
</thing-type>

</update:update-descriptions>

0 comments on commit d77efd7

Please sign in to comment.