Skip to content

Commit 6f9c87d

Browse files
authored
Add enhancements for better management of manufacturer specific clusters (#1423)
Signed-off-by: Chris Jackson <[email protected]>
1 parent f3d7e14 commit 6f9c87d

File tree

7 files changed

+194
-5
lines changed

7 files changed

+194
-5
lines changed

com.zsmartsystems.zigbee.console.main/src/main/java/com/zsmartsystems/zigbee/console/main/ZigBeeConsole.java

+5
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,15 @@
3737
import com.zsmartsystems.zigbee.ZigBeeNetworkState;
3838
import com.zsmartsystems.zigbee.ZigBeeNetworkStateListener;
3939
import com.zsmartsystems.zigbee.ZigBeeNode;
40+
import com.zsmartsystems.zigbee.console.ZigBeeConsoleAttributeAddCommand;
4041
import com.zsmartsystems.zigbee.console.ZigBeeConsoleAttributeReadCommand;
4142
import com.zsmartsystems.zigbee.console.ZigBeeConsoleAttributeSupportedCommand;
4243
import com.zsmartsystems.zigbee.console.ZigBeeConsoleAttributeWriteCommand;
4344
import com.zsmartsystems.zigbee.console.ZigBeeConsoleBindCommand;
4445
import com.zsmartsystems.zigbee.console.ZigBeeConsoleBindingTableCommand;
4546
import com.zsmartsystems.zigbee.console.ZigBeeConsoleCbkeCommand;
4647
import com.zsmartsystems.zigbee.console.ZigBeeConsoleChannelCommand;
48+
import com.zsmartsystems.zigbee.console.ZigBeeConsoleClusterCommand;
4749
import com.zsmartsystems.zigbee.console.ZigBeeConsoleColorCommand;
4850
import com.zsmartsystems.zigbee.console.ZigBeeConsoleCommand;
4951
import com.zsmartsystems.zigbee.console.ZigBeeConsoleCommandsSupportedCommand;
@@ -225,6 +227,9 @@ public ZigBeeConsole(final ZigBeeNetworkManager networkManager, final ZigBeeTran
225227
newCommands.put("identify", new ZigBeeConsoleIdentifyCommand());
226228
newCommands.put("reset", new ZigBeeConsoleNodeResetCommand());
227229

230+
newCommands.put("cluster", new ZigBeeConsoleClusterCommand());
231+
newCommands.put("attadd", new ZigBeeConsoleAttributeAddCommand());
232+
228233
zigBeeApi = new ZigBeeApi(networkManager);
229234

230235
networkManager.addNetworkStateListener(new ZigBeeNetworkStateListener() {

com.zsmartsystems.zigbee.console.main/src/main/java/com/zsmartsystems/zigbee/console/main/ZigBeeConsoleMain.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ public static void main(final String[] args) {
129129
ZclMeteringCluster.CLUSTER_ID, ZclElectricalMeasurementCluster.CLUSTER_ID,
130130
ZclDiagnosticsCluster.CLUSTER_ID, ZclPowerConfigurationCluster.CLUSTER_ID,
131131
ZclBallastConfigurationCluster.CLUSTER_ID, ZclOtaUpgradeCluster.CLUSTER_ID,
132-
ZclBinaryInputBasicCluster.CLUSTER_ID, 1000)
132+
ZclBinaryInputBasicCluster.CLUSTER_ID, ZclBallastConfigurationCluster.CLUSTER_ID, 1000, 0xff17)
133133
.collect(Collectors.toSet()));
134134

135135
final Set<Integer> supportedServerClusters = new TreeSet<>();
@@ -142,7 +142,8 @@ public static void main(final String[] args) {
142142
ZclElectricalMeasurementCluster.CLUSTER_ID,
143143
ZclDiagnosticsCluster.CLUSTER_ID, ZclBallastConfigurationCluster.CLUSTER_ID,
144144
ZclTemperatureMeasurementCluster.CLUSTER_ID, ZclIasZoneCluster.CLUSTER_ID,
145-
ZclWindowCoveringCluster.CLUSTER_ID, ZclBinaryInputBasicCluster.CLUSTER_ID, 1000)
145+
ZclWindowCoveringCluster.CLUSTER_ID, ZclBinaryInputBasicCluster.CLUSTER_ID,
146+
ZclBallastConfigurationCluster.CLUSTER_ID, 1000, 0xff17)
146147
.collect(Collectors.toSet()));
147148

148149
final TransportConfig transportOptions = new TransportConfig();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/**
2+
* Copyright (c) 2016-2024 by the respective copyright holders.
3+
* All rights reserved. This program and the accompanying materials
4+
* are made available under the terms of the Eclipse Public License v1.0
5+
* which accompanies this distribution, and is available at
6+
* http://www.eclipse.org/legal/epl-v10.html
7+
*/
8+
package com.zsmartsystems.zigbee.console;
9+
10+
import java.io.PrintStream;
11+
import java.util.ArrayList;
12+
import java.util.HashSet;
13+
import java.util.List;
14+
import java.util.Set;
15+
import java.util.concurrent.ExecutionException;
16+
import java.util.stream.Collectors;
17+
18+
import com.zsmartsystems.zigbee.ZigBeeEndpoint;
19+
import com.zsmartsystems.zigbee.ZigBeeNetworkManager;
20+
import com.zsmartsystems.zigbee.zcl.ZclAttribute;
21+
import com.zsmartsystems.zigbee.zcl.ZclCluster;
22+
import com.zsmartsystems.zigbee.zcl.protocol.ZclDataType;
23+
24+
/**
25+
*
26+
* @author Chris Jackson
27+
*
28+
*/
29+
public class ZigBeeConsoleAttributeAddCommand extends ZigBeeConsoleAbstractCommand {
30+
31+
@Override
32+
public String getCommand() {
33+
return "attadd";
34+
}
35+
36+
@Override
37+
public String getDescription() {
38+
return "Add an attribute.";
39+
}
40+
41+
@Override
42+
public String getSyntax() {
43+
return "ENDPOINT CLUSTER ATTRIBUTEID MANUFACTURER TYPE NAME";
44+
}
45+
46+
@Override
47+
public String getHelp() {
48+
return null;
49+
}
50+
51+
@Override
52+
public void process(ZigBeeNetworkManager networkManager, String[] args, PrintStream out)
53+
throws IllegalArgumentException, InterruptedException, ExecutionException {
54+
if (args.length < 6) {
55+
throw new IllegalArgumentException("Too few arguments");
56+
}
57+
58+
final ZigBeeEndpoint endpoint = getEndpoint(networkManager, args[1]);
59+
final ZclCluster cluster = getCluster(endpoint, args[2]);
60+
final Integer attributeId = parseAttribute(args[3]);
61+
final Integer manufacturerId = parseAttribute(args[4]);
62+
final ZclDataType dataType = ZclDataType.valueOf(args[5]);
63+
64+
List<String> nameList = new ArrayList<>();
65+
for (int cnt = 6; cnt < args.length; cnt++) {
66+
nameList.add(args[cnt]);
67+
}
68+
String name = nameList.stream().collect(Collectors.joining(" "));
69+
70+
final ZclAttribute attribute = new ZclAttribute(cluster, attributeId, name, dataType, false, true, true, true,
71+
manufacturerId);
72+
73+
Set<ZclAttribute> attributes = new HashSet<>();
74+
attributes.add(attribute);
75+
76+
cluster.addAttributes(attributes);
77+
out.println("Added attribute " + attribute);
78+
}
79+
}

com.zsmartsystems.zigbee.console/src/main/java/com/zsmartsystems/zigbee/console/ZigBeeConsoleAttributeWriteCommand.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public String getDescription() {
4141

4242
@Override
4343
public String getSyntax() {
44-
return "ENDPOINT CLUSTER ATTRIBUTEID (VALUE [TYPE] | {VALUE1 VALUE2 ... VALUEN} TYPE)";
44+
return "ENDPOINT CLUSTER ATTRIBUTEID (VALUE [TYPE] | {VALUE1 VALUE2 ... VALUEn} TYPE)";
4545
}
4646

4747
@Override
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/**
2+
* Copyright (c) 2016-2024 by the respective copyright holders.
3+
* All rights reserved. This program and the accompanying materials
4+
* are made available under the terms of the Eclipse Public License v1.0
5+
* which accompanies this distribution, and is available at
6+
* http://www.eclipse.org/legal/epl-v10.html
7+
*/
8+
package com.zsmartsystems.zigbee.console;
9+
10+
import java.io.PrintStream;
11+
import java.util.concurrent.ExecutionException;
12+
13+
import com.zsmartsystems.zigbee.ZigBeeEndpoint;
14+
import com.zsmartsystems.zigbee.ZigBeeNetworkManager;
15+
import com.zsmartsystems.zigbee.zcl.ZclCluster;
16+
17+
/**
18+
*
19+
* @author Chris Jackson
20+
*
21+
*/
22+
public class ZigBeeConsoleClusterCommand extends ZigBeeConsoleAbstractCommand {
23+
24+
@Override
25+
public String getCommand() {
26+
return "cluster";
27+
}
28+
29+
@Override
30+
public String getDescription() {
31+
return "Edit a cluster.";
32+
}
33+
34+
@Override
35+
public String getSyntax() {
36+
return "ENDPOINT CLUSTER [MANUFACTURER=id]";
37+
}
38+
39+
@Override
40+
public String getHelp() {
41+
return null;
42+
}
43+
44+
@Override
45+
public void process(ZigBeeNetworkManager networkManager, String[] args, PrintStream out)
46+
throws IllegalArgumentException, InterruptedException, ExecutionException {
47+
if (args.length < 3) {
48+
throw new IllegalArgumentException("Too few arguments");
49+
}
50+
51+
final ZigBeeEndpoint endpoint = getEndpoint(networkManager, args[1]);
52+
final ZclCluster cluster = getCluster(endpoint, args[2]);
53+
54+
Integer manufacturer = null;
55+
56+
for (int i = 3; i < args.length; i++) {
57+
String cmd[] = args[i].split("=");
58+
if (cmd != null && cmd.length == 2) {
59+
switch (cmd[0].toLowerCase()) {
60+
case "manufacturer":
61+
manufacturer = parseInteger(cmd[1]);
62+
break;
63+
default:
64+
break;
65+
}
66+
continue;
67+
}
68+
}
69+
70+
if (manufacturer != null) {
71+
if (cluster.setManufacturerCode(manufacturer)) {
72+
out.println("Manufacturer code set to " + manufacturer);
73+
} else {
74+
out.println("Error setting manufacturer code!");
75+
}
76+
}
77+
78+
out.println("Cluster updated: " + cluster.toString());
79+
}
80+
}

com.zsmartsystems.zigbee.console/src/main/java/com/zsmartsystems/zigbee/console/ZigBeeConsoleDeviceFingerprintCommand.java

+5-1
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,11 @@ private void getClusterInfo(PrintStream out, ZigBeeNetworkManager networkManager
204204
out.println(
205205
"| | | |>| Cluster " + String.format("%04X", cluster.getClusterId()) + " " + cluster.getClusterName());
206206
out.println("| | | | |> Type " + (cluster.isClient() ? "Client [Output]" : "Server [Input]"));
207-
out.println("| | | | |> Manufacturer Spec. " + (cluster.isManufacturerSpecific() ? "Yes" : "No"));
207+
out.print("| | | | |> Manufacturer Spec. " + (cluster.isManufacturerSpecific() ? "Yes" : "No"));
208+
if (cluster.isManufacturerSpecific()) {
209+
out.print(" [" + String.format("%04X", cluster.getManufacturerCode()) + "]");
210+
}
211+
out.println();
208212

209213
if ((cluster.isClient() && !networkManager.isClientClusterSupported(cluster.getClusterId())) ||
210214
(cluster.isServer() && !networkManager.isServerClusterSupported(cluster.getClusterId()))) {

com.zsmartsystems.zigbee/src/main/java/com/zsmartsystems/zigbee/zcl/ZclCluster.java

+21-1
Original file line numberDiff line numberDiff line change
@@ -1921,14 +1921,34 @@ public Future<CommandResult> getReporting(final ZclAttribute attribute) {
19211921
}
19221922

19231923
/**
1924-
* Indicates whether this is a manufacturer-specific attribute. Default is not manufacturer-specific.
1924+
* Set the manufacturer code; must be non-null for manufacturer-specific clusters.
1925+
*
1926+
* @param manufacturerCode the new manufacturer code - must be non-null for a manufacturer specific cluster
1927+
* @return true if the manufacturer code was updated. If the cluster already has a manufacturer specific code set,
1928+
* this will return false
1929+
*/
1930+
public boolean setManufacturerCode(int manufacturerCode) {
1931+
if (this.manufacturerCode != null) {
1932+
return false;
1933+
}
1934+
1935+
this.manufacturerCode = manufacturerCode;
1936+
return true;
1937+
}
1938+
1939+
/**
1940+
* Indicates whether this is a manufacturer-specific cluster. Default is not manufacturer-specific.
1941+
*
1942+
* @return true if this is a manufacturer-specific cluster
19251943
*/
19261944
public boolean isManufacturerSpecific() {
19271945
return getManufacturerCode() != null;
19281946
}
19291947

19301948
/**
19311949
* Returns the manufacturer code; must be non-null for manufacturer-specific clusters.
1950+
*
1951+
* @return the manufacturer code or null if this is not a manufacturer specific cluster
19321952
*/
19331953
public Integer getManufacturerCode() {
19341954
return manufacturerCode;

0 commit comments

Comments
 (0)