Skip to content

Commit bd64b98

Browse files
committed
Update
Signed-off-by: Chris Jackson <[email protected]>
1 parent d55a56b commit bd64b98

File tree

95 files changed

+887
-995
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

95 files changed

+887
-995
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@
44
bin/
55
target/
66
**/.settings/org.eclipse.*
7+
*.sh

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ using your real name (sorry, no pseudonyms or anonymous contributions.)
133133
There are several exceptions to the signing requirement. Currently these are:
134134

135135
* Your patch fixes spelling or grammar errors.
136-
* Your patch is a single line change to documentation.
136+
* Your patch is a small change to documentation.
137137

138138
## Community Guidelines
139139

org.openhab.binding.zigbee.tuya/src/main/java/org/openhab/binding/zigbee/tuya/TuyaBindingConstants.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
package org.openhab.binding.zigbee.tuya;
1414

1515
import org.eclipse.jdt.annotation.NonNullByDefault;
16+
import org.openhab.binding.zigbee.ZigBeeBindingConstants;
17+
import org.openhab.core.thing.ThingTypeUID;
1618
import org.openhab.core.thing.type.ChannelTypeUID;
1719

1820
/**
@@ -24,7 +26,9 @@
2426
@NonNullByDefault
2527
public class TuyaBindingConstants {
2628

27-
public static final String BINDING_ID = "zigbee";
29+
// List of Thing Type UIDs
30+
public final static ThingTypeUID THING_TYPE_TUYA_BLIND_AM25 = new ThingTypeUID(ZigBeeBindingConstants.BINDING_ID,
31+
"tuya_am25");
2832

2933
public static final String CHANNEL_NAME_TUYA_BUTTON = "tuyabutton";
3034
public static final String CHANNEL_LABEL_TUYA_BUTTON = "Button";
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package org.openhab.binding.zigbee.tuya.handler;
2+
3+
import org.openhab.binding.zigbee.converter.ZigBeeChannelConverterFactory;
4+
import org.openhab.binding.zigbee.handler.ZigBeeBaseThingHandler;
5+
import org.openhab.binding.zigbee.handler.ZigBeeIsAliveTracker;
6+
import org.openhab.core.thing.Thing;
7+
import org.slf4j.Logger;
8+
import org.slf4j.LoggerFactory;
9+
10+
import com.zsmartsystems.zigbee.ZigBeeEndpoint;
11+
import com.zsmartsystems.zigbee.ZigBeeNode;
12+
13+
/**
14+
* Handler for Tuya AM25 blinds
15+
*
16+
* @author Chris Jackson - Initial Contribution
17+
*
18+
*/
19+
public class TuyaBlindsThingHandler extends ZigBeeBaseThingHandler {
20+
private Logger logger = LoggerFactory.getLogger(TuyaBlindsThingHandler.class);
21+
22+
public TuyaBlindsThingHandler(Thing zigbeeDevice, ZigBeeChannelConverterFactory channelFactory,
23+
ZigBeeIsAliveTracker zigbeeIsAliveTracker) {
24+
super(zigbeeDevice, channelFactory, zigbeeIsAliveTracker);
25+
// TODO Auto-generated constructor stub
26+
}
27+
28+
@Override
29+
protected void doNodeInitialisation(ZigBeeNode node) {
30+
ZigBeeEndpoint endpoint = node.getEndpoint(1);
31+
if (endpoint == null) {
32+
logger.error("{}: Tuya blinds handler couldn't find endpoint 1", node.getIeeeAddress());
33+
return;
34+
}
35+
}
36+
37+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/**
2+
* Copyright (c) 2010-2021 Contributors to the openHAB project
3+
*
4+
* See the NOTICE file(s) distributed with this work for additional
5+
* information.
6+
*
7+
* This program and the accompanying materials are made available under the
8+
* terms of the Eclipse Public License 2.0 which is available at
9+
* http://www.eclipse.org/legal/epl-2.0
10+
*
11+
* SPDX-License-Identifier: EPL-2.0
12+
*/
13+
package org.openhab.binding.zigbee.tuya.internal;
14+
15+
import java.util.Hashtable;
16+
17+
import org.openhab.binding.zigbee.converter.ZigBeeChannelConverterFactory;
18+
import org.openhab.binding.zigbee.discovery.ZigBeeThingTypeMatcher;
19+
import org.openhab.binding.zigbee.handler.ZigBeeBaseThingHandler;
20+
import org.openhab.binding.zigbee.handler.ZigBeeGenericThingHandler;
21+
import org.openhab.binding.zigbee.handler.ZigBeeIsAliveTracker;
22+
import org.openhab.binding.zigbee.tuya.TuyaBindingConstants;
23+
import org.openhab.binding.zigbee.tuya.handler.TuyaBlindsThingHandler;
24+
import org.openhab.core.config.core.ConfigDescriptionProvider;
25+
import org.openhab.core.thing.Thing;
26+
import org.openhab.core.thing.ThingTypeUID;
27+
import org.openhab.core.thing.binding.BaseThingHandlerFactory;
28+
import org.openhab.core.thing.binding.ThingHandler;
29+
import org.openhab.core.thing.binding.ThingHandlerFactory;
30+
import org.openhab.core.thing.type.DynamicStateDescriptionProvider;
31+
import org.osgi.service.component.annotations.Component;
32+
import org.osgi.service.component.annotations.Reference;
33+
34+
/**
35+
* The {@link TuyaHandlerFactory} is responsible for creating things and thing
36+
* handlers for Tuya devices.
37+
*
38+
* @author Chris Jackson - Initial contribution
39+
*/
40+
@Component(service = ThingHandlerFactory.class)
41+
public class TuyaHandlerFactory extends BaseThingHandlerFactory {
42+
43+
private final ZigBeeThingTypeMatcher matcher = new ZigBeeThingTypeMatcher();
44+
45+
private ZigBeeChannelConverterFactory zigbeeChannelConverterFactory;
46+
private ZigBeeIsAliveTracker zigbeeIsAliveTracker;
47+
48+
@Override
49+
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
50+
return matcher.getSupportedThingTypeUIDs().contains(thingTypeUID);
51+
}
52+
53+
@Override
54+
protected ThingHandler createHandler(Thing thing) {
55+
if (!supportsThingType(thing.getThingTypeUID())) {
56+
return null;
57+
}
58+
59+
ZigBeeBaseThingHandler handler;
60+
61+
// Check for thing types with a custom thing handler
62+
if (thing.getThingTypeUID().equals(TuyaBindingConstants.THING_TYPE_TUYA_BLIND_AM25)) {
63+
handler = new TuyaBlindsThingHandler(thing, zigbeeChannelConverterFactory, zigbeeIsAliveTracker);
64+
} else {
65+
handler = new ZigBeeGenericThingHandler(thing, zigbeeChannelConverterFactory, zigbeeIsAliveTracker);
66+
}
67+
68+
bundleContext.registerService(ConfigDescriptionProvider.class.getName(), handler,
69+
new Hashtable<String, Object>());
70+
bundleContext.registerService(DynamicStateDescriptionProvider.class.getName(), handler,
71+
new Hashtable<String, Object>());
72+
73+
return handler;
74+
}
75+
76+
@Reference
77+
protected void setZigBeeChannelConverterFactory(ZigBeeChannelConverterFactory zigbeeChannelConverterFactory) {
78+
this.zigbeeChannelConverterFactory = zigbeeChannelConverterFactory;
79+
}
80+
81+
protected void unsetZigBeeChannelConverterFactory(ZigBeeChannelConverterFactory zigbeeChannelConverterFactory) {
82+
this.zigbeeChannelConverterFactory = null;
83+
}
84+
85+
@Reference
86+
protected void setZigbeeIsAliveTracker(ZigBeeIsAliveTracker zigbeeIsAliveTracker) {
87+
this.zigbeeIsAliveTracker = zigbeeIsAliveTracker;
88+
}
89+
90+
protected void unsetZigbeeIsAliveTracker(ZigBeeIsAliveTracker zigbeeIsAliveTracker) {
91+
this.zigbeeIsAliveTracker = null;
92+
}
93+
}
Lines changed: 25 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -10,29 +10,28 @@
1010
*
1111
* SPDX-License-Identifier: EPL-2.0
1212
*/
13-
package org.openhab.binding.zigbee.tuya.converter;
13+
package org.openhab.binding.zigbee.tuya.internal.converter;
1414

15-
import static java.lang.Integer.*;
15+
import static java.lang.Integer.toHexString;
1616

1717
import java.util.Collections;
1818
import java.util.HashMap;
1919
import java.util.Set;
2020
import java.util.concurrent.ExecutionException;
2121

22+
import org.openhab.binding.zigbee.converter.ZigBeeBaseChannelConverter;
23+
import org.openhab.binding.zigbee.handler.ZigBeeBaseThingHandler;
24+
import org.openhab.binding.zigbee.internal.converter.config.ZclReportingConfig;
25+
import org.openhab.binding.zigbee.tuya.internal.zigbee.TuyaButtonPressCommand;
2226
import org.openhab.core.thing.Channel;
2327
import org.openhab.core.thing.CommonTriggerEvents;
2428
import org.openhab.core.thing.ThingUID;
25-
import org.openhab.binding.zigbee.converter.ZigBeeBaseChannelConverter;
26-
import org.openhab.binding.zigbee.handler.ZigBeeThingHandler;
27-
import org.openhab.binding.zigbee.internal.converter.config.ZclReportingConfig;
28-
import org.openhab.binding.zigbee.tuya.internal.TuyaButtonPressCommand;
2929
import org.slf4j.Logger;
3030
import org.slf4j.LoggerFactory;
3131

3232
import com.zsmartsystems.zigbee.CommandResult;
3333
import com.zsmartsystems.zigbee.ZigBeeEndpoint;
3434
import com.zsmartsystems.zigbee.zcl.ZclAttribute;
35-
import com.zsmartsystems.zigbee.zcl.ZclAttributeListener;
3635
import com.zsmartsystems.zigbee.zcl.ZclCluster;
3736
import com.zsmartsystems.zigbee.zcl.ZclCommand;
3837
import com.zsmartsystems.zigbee.zcl.ZclCommandListener;
@@ -47,19 +46,18 @@
4746
* As the configuration is done via channel properties, this converter is usable via static thing types only.
4847
*
4948
* @author Daniel Schall - initial contribution
49+
* @author Chris Jackson - minor updates and refactoring to separate bundle
5050
*/
51-
public class ZigBeeConverterTuyaButton extends ZigBeeBaseChannelConverter
52-
implements ZclAttributeListener, ZclCommandListener {
51+
public class ZigBeeConverterTuyaButton extends ZigBeeBaseChannelConverter implements ZclCommandListener {
5352

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

5655
private ZclCluster clientCluster = null;
57-
private ZclCluster serverCluster = null;
5856

5957
// Tuya devices sometimes send duplicate commands with the same tx id.
6058
// We keep track of the last received Tx id and ignore the duplicate.
6159
private Integer lastTxId = -1;
62-
60+
6361
@Override
6462
public Set<Integer> getImplementedClientClusters() {
6563
return Collections.singleton(ZclOnOffCluster.CLUSTER_ID);
@@ -77,13 +75,14 @@ public boolean initializeDevice() {
7775

7876
if (clientCluster == null) {
7977
logger.error("{}: Error opening client cluster {} on endpoint {}", endpoint.getIeeeAddress(),
80-
ZclOnOffCluster.CLUSTER_ID, endpoint.getEndpointId());
78+
ZclOnOffCluster.CLUSTER_ID, endpoint.getEndpointId());
8179
return false;
8280
}
8381

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

@@ -115,34 +114,26 @@ public boolean initializeDevice() {
115114
}
116115
} catch (InterruptedException | ExecutionException e) {
117116
logger.error("{}: Exception setting client binding to cluster {}: {}", endpoint.getIeeeAddress(),
118-
ZclOnOffCluster.CLUSTER_ID, e);
117+
ZclOnOffCluster.CLUSTER_ID, e);
119118
}
120119

121120
return true;
122121
}
123122

124123
@Override
125-
public synchronized boolean initializeConverter(ZigBeeThingHandler thing) {
124+
public synchronized boolean initializeConverter(ZigBeeBaseThingHandler thing) {
126125
super.initializeConverter(thing);
127126

128127
clientCluster = endpoint.getOutputCluster(ZclOnOffCluster.CLUSTER_ID);
129-
serverCluster = endpoint.getInputCluster(ZclOnOffCluster.CLUSTER_ID);
130128

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

136-
if (serverCluster == null) {
137-
logger.error("{}: Error opening device server controls", endpoint.getIeeeAddress());
138-
return false;
139-
}
140-
141134
clientCluster.addCommandListener(this);
142-
serverCluster.addAttributeListener(this);
143135

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

153144
@Override
154145
public void disposeConverter() {
155-
if(clientCluster != null) {
146+
if (clientCluster != null) {
156147
clientCluster.removeCommandListener(this);
157148
}
158-
if (serverCluster != null) {
159-
serverCluster.removeAttributeListener(this);
160-
}
161-
}
162-
163-
@Override
164-
public void handleRefresh() {
165-
// nothing to do, as we only listen to commands
166149
}
167150

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

175158
@Override
176159
public boolean commandReceived(ZclCommand command) {
177-
logger.debug("{} received command {}", endpoint.getIeeeAddress(), command);
160+
logger.debug("{}: Received command {}", endpoint.getIeeeAddress(), command);
178161
Integer thisTxId = command.getTransactionId();
179-
if(lastTxId == thisTxId)
180-
{
181-
logger.debug("{} ignoring duplicate command {}", endpoint.getIeeeAddress(), thisTxId);
182-
}
183-
else if (command instanceof TuyaButtonPressCommand) {
162+
if (lastTxId == thisTxId) {
163+
logger.debug("{}: Ignoring duplicate command {}", endpoint.getIeeeAddress(), thisTxId);
164+
} else if (command instanceof TuyaButtonPressCommand) {
184165
TuyaButtonPressCommand tuyaButtonPressCommand = (TuyaButtonPressCommand) command;
185-
thing.triggerChannel(channel.getUID(), getEventType(tuyaButtonPressCommand.getPressType()));
186-
clientCluster.sendDefaultResponse(command, ZclStatus.SUCCESS);
187-
}
188-
else {
189-
logger.warn("{} received unknown command {}", endpoint.getIeeeAddress(), command);
166+
thing.triggerChannel(channel.getUID(), getEventType(tuyaButtonPressCommand.getPressType()));
167+
clientCluster.sendDefaultResponse(command, ZclStatus.SUCCESS);
168+
} else {
169+
logger.warn("{}: Received unknown command {}", endpoint.getIeeeAddress(), command);
190170
}
191171

192172
lastTxId = thisTxId;
193173
return true;
194174
}
195175

196-
@Override
197-
public void attributeUpdated(ZclAttribute attribute, Object val) {
198-
logger.debug("{}: ZigBee attribute reports {}", endpoint.getIeeeAddress(), attribute);
199-
}
200-
201-
private String getEventType(Integer pressType)
202-
{
203-
switch(pressType)
204-
{
176+
private String getEventType(Integer pressType) {
177+
switch (pressType) {
205178
case 0:
206179
return CommonTriggerEvents.SHORT_PRESSED;
207180
case 1:
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,15 @@
1010
*
1111
* SPDX-License-Identifier: EPL-2.0
1212
*/
13-
package org.openhab.binding.zigbee.tuya.converter;
13+
package org.openhab.binding.zigbee.tuya.internal.converter;
1414

1515
import java.util.HashMap;
1616
import java.util.Map;
1717

18-
import org.openhab.binding.zigbee.ZigBeeBindingConstants;
1918
import org.openhab.binding.zigbee.converter.ZigBeeBaseChannelConverter;
2019
import org.openhab.binding.zigbee.converter.ZigBeeChannelConverterFactory;
2120
import org.openhab.binding.zigbee.converter.ZigBeeChannelConverterProvider;
21+
import org.openhab.binding.zigbee.tuya.TuyaBindingConstants;
2222
import org.openhab.core.thing.type.ChannelTypeUID;
2323
import org.osgi.service.component.annotations.Component;
2424

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

3636
public ZigBeeTuyaChannelConverterProvider() {
3737
// Add all the converters into the map...
38-
channelMap.put(ZigBeeBindingConstants.CHANNEL_COLOR_COLOR, ZigBeeConverterTuyaButton.class);
38+
channelMap.put(TuyaBindingConstants.CHANNEL_TUYA_BUTTON, ZigBeeConverterTuyaButton.class);
3939
}
4040

4141
@Override

org.openhab.binding.zigbee.tuya/src/main/java/org/openhab/binding/zigbee/tuya/internal/discovery/ZigBeeTuyaDiscoveryParticipant.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
import java.util.Set;
1717

1818
import org.openhab.binding.zigbee.discovery.ZigBeeDiscoveryParticipant;
19-
import org.openhab.binding.zigbee.internal.ZigBeeThingTypeMatcher;
19+
import org.openhab.binding.zigbee.discovery.ZigBeeThingTypeMatcher;
2020
import org.openhab.core.config.discovery.DiscoveryResult;
2121
import org.openhab.core.config.discovery.DiscoveryResultBuilder;
2222
import org.openhab.core.thing.Thing;

0 commit comments

Comments
 (0)