Skip to content

Commit

Permalink
Update
Browse files Browse the repository at this point in the history
Signed-off-by: Chris Jackson <[email protected]>
  • Loading branch information
cdjackson committed Nov 18, 2021
1 parent b4fd66b commit fa8f2c9
Show file tree
Hide file tree
Showing 95 changed files with 887 additions and 995 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
bin/
target/
**/.settings/org.eclipse.*
*.sh
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ using your real name (sorry, no pseudonyms or anonymous contributions.)
There are several exceptions to the signing requirement. Currently these are:

* Your patch fixes spelling or grammar errors.
* Your patch is a single line change to documentation.
* Your patch is a small change to documentation.

## Community Guidelines

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
package org.openhab.binding.zigbee.tuya;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.binding.zigbee.ZigBeeBindingConstants;
import org.openhab.core.thing.ThingTypeUID;
import org.openhab.core.thing.type.ChannelTypeUID;

/**
Expand All @@ -24,7 +26,9 @@
@NonNullByDefault
public class TuyaBindingConstants {

public static final String BINDING_ID = "zigbee";
// List of Thing Type UIDs
public final static ThingTypeUID THING_TYPE_TUYA_BLIND_AM25 = new ThingTypeUID(ZigBeeBindingConstants.BINDING_ID,
"tuya_am25");

public static final String CHANNEL_NAME_TUYA_BUTTON = "tuyabutton";
public static final String CHANNEL_LABEL_TUYA_BUTTON = "Button";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package org.openhab.binding.zigbee.tuya.handler;

import org.openhab.binding.zigbee.converter.ZigBeeChannelConverterFactory;
import org.openhab.binding.zigbee.handler.ZigBeeBaseThingHandler;
import org.openhab.binding.zigbee.handler.ZigBeeIsAliveTracker;
import org.openhab.core.thing.Thing;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.zsmartsystems.zigbee.ZigBeeEndpoint;
import com.zsmartsystems.zigbee.ZigBeeNode;

/**
* Handler for Tuya AM25 blinds
*
* @author Chris Jackson - Initial Contribution
*
*/
public class TuyaBlindsThingHandler extends ZigBeeBaseThingHandler {
private Logger logger = LoggerFactory.getLogger(TuyaBlindsThingHandler.class);

public TuyaBlindsThingHandler(Thing zigbeeDevice, ZigBeeChannelConverterFactory channelFactory,
ZigBeeIsAliveTracker zigbeeIsAliveTracker) {
super(zigbeeDevice, channelFactory, zigbeeIsAliveTracker);
// TODO Auto-generated constructor stub
}

@Override
protected void doNodeInitialisation(ZigBeeNode node) {
ZigBeeEndpoint endpoint = node.getEndpoint(1);
if (endpoint == null) {
logger.error("{}: Tuya blinds handler couldn't find endpoint 1", node.getIeeeAddress());
return;
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/**
* 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.zigbee.tuya.internal;

import java.util.Hashtable;

import org.openhab.binding.zigbee.converter.ZigBeeChannelConverterFactory;
import org.openhab.binding.zigbee.discovery.ZigBeeThingTypeMatcher;
import org.openhab.binding.zigbee.handler.ZigBeeBaseThingHandler;
import org.openhab.binding.zigbee.handler.ZigBeeGenericThingHandler;
import org.openhab.binding.zigbee.handler.ZigBeeIsAliveTracker;
import org.openhab.binding.zigbee.tuya.TuyaBindingConstants;
import org.openhab.binding.zigbee.tuya.handler.TuyaBlindsThingHandler;
import org.openhab.core.config.core.ConfigDescriptionProvider;
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.openhab.core.thing.type.DynamicStateDescriptionProvider;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;

/**
* The {@link TuyaHandlerFactory} is responsible for creating things and thing
* handlers for Tuya devices.
*
* @author Chris Jackson - Initial contribution
*/
@Component(service = ThingHandlerFactory.class)
public class TuyaHandlerFactory extends BaseThingHandlerFactory {

private final ZigBeeThingTypeMatcher matcher = new ZigBeeThingTypeMatcher();

private ZigBeeChannelConverterFactory zigbeeChannelConverterFactory;
private ZigBeeIsAliveTracker zigbeeIsAliveTracker;

@Override
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
return matcher.getSupportedThingTypeUIDs().contains(thingTypeUID);
}

@Override
protected ThingHandler createHandler(Thing thing) {
if (!supportsThingType(thing.getThingTypeUID())) {
return null;
}

ZigBeeBaseThingHandler handler;

// Check for thing types with a custom thing handler
if (thing.getThingTypeUID().equals(TuyaBindingConstants.THING_TYPE_TUYA_BLIND_AM25)) {
handler = new TuyaBlindsThingHandler(thing, zigbeeChannelConverterFactory, zigbeeIsAliveTracker);
} else {
handler = new ZigBeeGenericThingHandler(thing, zigbeeChannelConverterFactory, zigbeeIsAliveTracker);
}

bundleContext.registerService(ConfigDescriptionProvider.class.getName(), handler,
new Hashtable<String, Object>());
bundleContext.registerService(DynamicStateDescriptionProvider.class.getName(), handler,
new Hashtable<String, Object>());

return handler;
}

@Reference
protected void setZigBeeChannelConverterFactory(ZigBeeChannelConverterFactory zigbeeChannelConverterFactory) {
this.zigbeeChannelConverterFactory = zigbeeChannelConverterFactory;
}

protected void unsetZigBeeChannelConverterFactory(ZigBeeChannelConverterFactory zigbeeChannelConverterFactory) {
this.zigbeeChannelConverterFactory = null;
}

@Reference
protected void setZigbeeIsAliveTracker(ZigBeeIsAliveTracker zigbeeIsAliveTracker) {
this.zigbeeIsAliveTracker = zigbeeIsAliveTracker;
}

protected void unsetZigbeeIsAliveTracker(ZigBeeIsAliveTracker zigbeeIsAliveTracker) {
this.zigbeeIsAliveTracker = null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,29 +10,28 @@
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.zigbee.tuya.converter;
package org.openhab.binding.zigbee.tuya.internal.converter;

import static java.lang.Integer.*;
import static java.lang.Integer.toHexString;

import java.util.Collections;
import java.util.HashMap;
import java.util.Set;
import java.util.concurrent.ExecutionException;

import org.openhab.binding.zigbee.converter.ZigBeeBaseChannelConverter;
import org.openhab.binding.zigbee.handler.ZigBeeBaseThingHandler;
import org.openhab.binding.zigbee.internal.converter.config.ZclReportingConfig;
import org.openhab.binding.zigbee.tuya.internal.zigbee.TuyaButtonPressCommand;
import org.openhab.core.thing.Channel;
import org.openhab.core.thing.CommonTriggerEvents;
import org.openhab.core.thing.ThingUID;
import org.openhab.binding.zigbee.converter.ZigBeeBaseChannelConverter;
import org.openhab.binding.zigbee.handler.ZigBeeThingHandler;
import org.openhab.binding.zigbee.internal.converter.config.ZclReportingConfig;
import org.openhab.binding.zigbee.tuya.internal.TuyaButtonPressCommand;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.zsmartsystems.zigbee.CommandResult;
import com.zsmartsystems.zigbee.ZigBeeEndpoint;
import com.zsmartsystems.zigbee.zcl.ZclAttribute;
import com.zsmartsystems.zigbee.zcl.ZclAttributeListener;
import com.zsmartsystems.zigbee.zcl.ZclCluster;
import com.zsmartsystems.zigbee.zcl.ZclCommand;
import com.zsmartsystems.zigbee.zcl.ZclCommandListener;
Expand All @@ -47,19 +46,18 @@
* As the configuration is done via channel properties, this converter is usable via static thing types only.
*
* @author Daniel Schall - initial contribution
* @author Chris Jackson - minor updates and refactoring to separate bundle
*/
public class ZigBeeConverterTuyaButton extends ZigBeeBaseChannelConverter
implements ZclAttributeListener, ZclCommandListener {
public class ZigBeeConverterTuyaButton extends ZigBeeBaseChannelConverter implements ZclCommandListener {

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

private ZclCluster clientCluster = null;
private ZclCluster serverCluster = null;

// Tuya devices sometimes send duplicate commands with the same tx id.
// We keep track of the last received Tx id and ignore the duplicate.
private Integer lastTxId = -1;

@Override
public Set<Integer> getImplementedClientClusters() {
return Collections.singleton(ZclOnOffCluster.CLUSTER_ID);
Expand All @@ -77,13 +75,14 @@ public boolean initializeDevice() {

if (clientCluster == null) {
logger.error("{}: Error opening client cluster {} on endpoint {}", endpoint.getIeeeAddress(),
ZclOnOffCluster.CLUSTER_ID, endpoint.getEndpointId());
ZclOnOffCluster.CLUSTER_ID, endpoint.getEndpointId());
return false;
}

// TODO Server side is not used in operation, so is it needed here?
if (serverCluster == null) {
logger.error("{}: Error opening server cluster {} on endpoint {}", endpoint.getIeeeAddress(),
ZclOnOffCluster.CLUSTER_ID, endpoint.getEndpointId());
ZclOnOffCluster.CLUSTER_ID, endpoint.getEndpointId());
return false;
}

Expand Down Expand Up @@ -115,34 +114,26 @@ public boolean initializeDevice() {
}
} catch (InterruptedException | ExecutionException e) {
logger.error("{}: Exception setting client binding to cluster {}: {}", endpoint.getIeeeAddress(),
ZclOnOffCluster.CLUSTER_ID, e);
ZclOnOffCluster.CLUSTER_ID, e);
}

return true;
}

@Override
public synchronized boolean initializeConverter(ZigBeeThingHandler thing) {
public synchronized boolean initializeConverter(ZigBeeBaseThingHandler thing) {
super.initializeConverter(thing);

clientCluster = endpoint.getOutputCluster(ZclOnOffCluster.CLUSTER_ID);
serverCluster = endpoint.getInputCluster(ZclOnOffCluster.CLUSTER_ID);

if (clientCluster == null) {
logger.error("{}: Error opening device client controls", endpoint.getIeeeAddress());
return false;
}

if (serverCluster == null) {
logger.error("{}: Error opening device server controls", endpoint.getIeeeAddress());
return false;
}

clientCluster.addCommandListener(this);
serverCluster.addAttributeListener(this);

// Add Tuya-specific command
//
HashMap<Integer, Class<? extends ZclCommand>> commandMap = new HashMap<>();
commandMap.put(TuyaButtonPressCommand.COMMAND_ID, TuyaButtonPressCommand.class);
clientCluster.addClientCommands(commandMap);
Expand All @@ -152,17 +143,9 @@ public synchronized boolean initializeConverter(ZigBeeThingHandler thing) {

@Override
public void disposeConverter() {
if(clientCluster != null) {
if (clientCluster != null) {
clientCluster.removeCommandListener(this);
}
if (serverCluster != null) {
serverCluster.removeAttributeListener(this);
}
}

@Override
public void handleRefresh() {
// nothing to do, as we only listen to commands
}

@Override
Expand All @@ -174,34 +157,24 @@ public Channel getChannel(ThingUID thingUID, ZigBeeEndpoint endpoint) {

@Override
public boolean commandReceived(ZclCommand command) {
logger.debug("{} received command {}", endpoint.getIeeeAddress(), command);
logger.debug("{}: Received command {}", endpoint.getIeeeAddress(), command);
Integer thisTxId = command.getTransactionId();
if(lastTxId == thisTxId)
{
logger.debug("{} ignoring duplicate command {}", endpoint.getIeeeAddress(), thisTxId);
}
else if (command instanceof TuyaButtonPressCommand) {
if (lastTxId == thisTxId) {
logger.debug("{}: Ignoring duplicate command {}", endpoint.getIeeeAddress(), thisTxId);
} else if (command instanceof TuyaButtonPressCommand) {
TuyaButtonPressCommand tuyaButtonPressCommand = (TuyaButtonPressCommand) command;
thing.triggerChannel(channel.getUID(), getEventType(tuyaButtonPressCommand.getPressType()));
clientCluster.sendDefaultResponse(command, ZclStatus.SUCCESS);
}
else {
logger.warn("{} received unknown command {}", endpoint.getIeeeAddress(), command);
thing.triggerChannel(channel.getUID(), getEventType(tuyaButtonPressCommand.getPressType()));
clientCluster.sendDefaultResponse(command, ZclStatus.SUCCESS);
} else {
logger.warn("{}: Received unknown command {}", endpoint.getIeeeAddress(), command);
}

lastTxId = thisTxId;
return true;
}

@Override
public void attributeUpdated(ZclAttribute attribute, Object val) {
logger.debug("{}: ZigBee attribute reports {}", endpoint.getIeeeAddress(), attribute);
}

private String getEventType(Integer pressType)
{
switch(pressType)
{
private String getEventType(Integer pressType) {
switch (pressType) {
case 0:
return CommonTriggerEvents.SHORT_PRESSED;
case 1:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.zigbee.tuya.converter;
package org.openhab.binding.zigbee.tuya.internal.converter;

import java.util.HashMap;
import java.util.Map;

import org.openhab.binding.zigbee.ZigBeeBindingConstants;
import org.openhab.binding.zigbee.converter.ZigBeeBaseChannelConverter;
import org.openhab.binding.zigbee.converter.ZigBeeChannelConverterFactory;
import org.openhab.binding.zigbee.converter.ZigBeeChannelConverterProvider;
import org.openhab.binding.zigbee.tuya.TuyaBindingConstants;
import org.openhab.core.thing.type.ChannelTypeUID;
import org.osgi.service.component.annotations.Component;

Expand All @@ -35,7 +35,7 @@ public final class ZigBeeTuyaChannelConverterProvider implements ZigBeeChannelCo

public ZigBeeTuyaChannelConverterProvider() {
// Add all the converters into the map...
channelMap.put(ZigBeeBindingConstants.CHANNEL_COLOR_COLOR, ZigBeeConverterTuyaButton.class);
channelMap.put(TuyaBindingConstants.CHANNEL_TUYA_BUTTON, ZigBeeConverterTuyaButton.class);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import java.util.Set;

import org.openhab.binding.zigbee.discovery.ZigBeeDiscoveryParticipant;
import org.openhab.binding.zigbee.internal.ZigBeeThingTypeMatcher;
import org.openhab.binding.zigbee.discovery.ZigBeeThingTypeMatcher;
import org.openhab.core.config.discovery.DiscoveryResult;
import org.openhab.core.config.discovery.DiscoveryResultBuilder;
import org.openhab.core.thing.Thing;
Expand Down
Loading

0 comments on commit fa8f2c9

Please sign in to comment.