Skip to content
This repository has been archived by the owner on Mar 27, 2024. It is now read-only.

Commit

Permalink
Implemented serialization of network state to ZigBeeApi and ZigBeeCon…
Browse files Browse the repository at this point in the history
…sole. Enables instantaneous startup of console after first startup which includes initial network browsing. Network state is serialized as JSON and for this added jackson dependency. fixes #11
  • Loading branch information
tlaukkan committed Mar 7, 2015
1 parent ee08c24 commit 01909c0
Show file tree
Hide file tree
Showing 21 changed files with 424 additions and 130 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ target/
.svn
*.iml
*.log
*.json
zigbee-api/build
.gradle
zigbee-console/build
Expand Down
6 changes: 6 additions & 0 deletions zigbee-api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,12 @@
<version>1.8</version>
</dependency>

<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.2</version>
</dependency>

</dependencies>

</project>
72 changes: 45 additions & 27 deletions zigbee-api/src/main/java/org/bubblecloud/zigbee/ZigBeeApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import org.bubblecloud.zigbee.network.EndpointListener;
import org.bubblecloud.zigbee.network.ZigBeeEndpoint;
import org.bubblecloud.zigbee.network.discovery.ZigBeeDiscoveryManager;
import org.bubblecloud.zigbee.network.impl.NetworkStateSerializer;
import org.bubblecloud.zigbee.network.impl.ZigBeeNetwork;
import org.bubblecloud.zigbee.network.model.DiscoveryMode;
import org.bubblecloud.zigbee.network.model.DriverStatus;
Expand Down Expand Up @@ -98,33 +99,7 @@ public ZigBeeApi(final ZigBeePort port, final int pan, final int channel,
public ZigBeeApi(final ZigBeePort port, final int pan, final int channel,
final boolean resetNetwork, final EnumSet<DiscoveryMode> discoveryModes) {
networkManager = new ZigBeeNetworkManagerImpl(port, NetworkMode.Coordinator, pan, channel, resetNetwork, 2500L);

discoveryManager = new ZigBeeDiscoveryManager(networkManager, discoveryModes);
}


/**
* Starts up network manager, network, context and discovery manager.
*
* @return true if startup was success.
*/
public boolean startup() {
networkManager.startup();

while (true) {
if (networkManager.getDriverStatus() == DriverStatus.NETWORK_READY) {
break;
}
if (networkManager.getDriverStatus() == DriverStatus.CLOSED) {
return false;
}
try {
Thread.sleep(100);
} catch (final InterruptedException e) {
return false;
}
}

network = ApplicationFrameworkLayer.getAFLayer(networkManager).getZigBeeNetwork();

network.addEndpointListenerListener(this);
Expand Down Expand Up @@ -165,10 +140,34 @@ public boolean startup() {
}
}

ApplicationFrameworkLayer.getAFLayer(networkManager).createDefaultSendingEndPoint();
}


/**
* Starts up network manager, network, context and discovery manager.
*
* @return true if startup was success.
*/
public boolean startup() {
networkManager.startup();
context.addDeviceListener(this);

while (true) {
if (networkManager.getDriverStatus() == DriverStatus.NETWORK_READY) {
break;
}
if (networkManager.getDriverStatus() == DriverStatus.CLOSED) {
return false;
}
try {
Thread.sleep(100);
} catch (final InterruptedException e) {
return false;
}
}

ApplicationFrameworkLayer.getAFLayer(networkManager).createDefaultSendingEndPoint();

discoveryManager.startup();

return true;
Expand All @@ -193,6 +192,25 @@ public void shutdown() {
networkManager.shutdown();
}

/**
* Serializes network state.
* @return the network state
*/
public String serializeNetworkState() {
final NetworkStateSerializer networkStateSerializer = new NetworkStateSerializer();
return networkStateSerializer.serialize(network);
}

/**
* Deserialize network state.
* @param networkState the network state
*/
public void deserializeNetworkState(final String networkState) {
final NetworkStateSerializer networkStateSerializer = new NetworkStateSerializer();
networkStateSerializer.deserialize(networkManager, network, networkState);
}


/**
* Gets ZigBee network manager.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ public interface Device extends ZigBeeEndpoint {
/**
* This method modify the <i>Binding Table</i> of physical device by adding the following entry:
* <pre>
* this.getNode().getIEEEAddress(), this.getDeviceTypeId(), clusterId, device.getNode().getIEEEAddress(), device.getDeviceTypeId()
* this.getNode().getIeeeAddress(), this.getDeviceTypeId(), clusterId, device.getNode().getIeeeAddress(), device.getDeviceTypeId()
* </pre>
*
* @param device {@link org.bubblecloud.zigbee.network.ZigBeeEndpoint} the device proxy that we want to bound to
Expand All @@ -150,7 +150,7 @@ public interface Device extends ZigBeeEndpoint {
/**
* This method modify the <i>Binding Table</i> of physical device by removing the entry if exists
* <pre>
* this.getNode().getIEEEAddress(), this.getDeviceTypeId(), clusterId, device.getNode().getIEEEAddress(), device.getDeviceTypeId()
* this.getNode().getIeeeAddress(), this.getDeviceTypeId(), clusterId, device.getNode().getIeeeAddress(), device.getDeviceTypeId()
* </pre>
*
* @param device {@link org.bubblecloud.zigbee.network.ZigBeeEndpoint} the device that we want to bound to
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Arrays;


/**
* This class represent a generic <b>Home Automation Device</b> as defined by the document:<br>
Expand Down Expand Up @@ -440,7 +438,7 @@ public int getNetworkAddress() {
}

@Override
public String getIEEEAddress() {
return endpoint.getIEEEAddress();
public String getIeeeAddress() {
return endpoint.getIeeeAddress();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ public Reporter getReporter() {

private Object doClusterWideRead() throws ZigBeeClusterException {

logger.info("Reading " + getName() + " from " + zbDevice.getIEEEAddress());
logger.info("Reading " + getName() + " from " + zbDevice.getIeeeAddress());
ReadAttributeCommand readAttrCom = new ReadAttributeCommand(new int[]{getId()});
ZCLFrame frame = new ZCLFrame(readAttrCom, zclCluster.isDefaultResponseEnabled());
ClusterMessageImpl input;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ public Response invoke(Command cmd) throws ZigBeeClusterException {
public Response invoke(Command cmd, boolean suppressResponse) throws ZigBeeClusterException {
ZCLFrame inFrame = new ZCLFrame(cmd, isDefaultResponseEnabled);
ClusterMessage input = new ClusterMessageImpl(getId(), inFrame);
logger.info("Sending {} command to {} (#{}).", cmd.getClass().getSimpleName(), zbDevice.getEndpointId(),
logger.debug("Sending {} command to {} (#{}).", cmd.getClass().getSimpleName(), zbDevice.getEndpointId(),
zbDevice.getNetworkAddress());
if (suppressResponse) {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public interface ZigBeeEndpoint {
/**
* @return a {@link String} representing the IEEEAddress of the node
*/
public String getIEEEAddress();
public String getIeeeAddress();

/**
* @return Address of the EndPoint represented by this object, value ranges from 1 to 240.
Expand Down Expand Up @@ -140,7 +140,7 @@ public interface ZigBeeEndpoint {
/**
* This method modify the <i>Binding Table</i> of physical endpoint by adding the following entry:
* <pre>
* this.getNode().getIEEEAddress(), this.getDeviceTypeId(), clusterId, endpoint.getNode().getIEEEAddress(), endpoint.getDeviceTypeId()
* this.getNode().getIeeeAddress(), this.getDeviceTypeId(), clusterId, endpoint.getNode().getIeeeAddress(), endpoint.getDeviceTypeId()
* </pre>
*
* @param endpoint {@link ZigBeeEndpoint} the endpoint that we want to bound to
Expand All @@ -154,7 +154,7 @@ public interface ZigBeeEndpoint {
/**
* This method modify the <i>Binding Table</i> of physical device by removing the entry if exists
* <pre>
* this.getNode().getIEEEAddress(), this.getDeviceTypeId(), clusterId, device.getNode().getIEEEAddress(), device.getDeviceTypeId()
* this.getNode().getIeeeAddress(), this.getDeviceTypeId(), clusterId, device.getNode().getIeeeAddress(), device.getDeviceTypeId()
* </pre>
*
* @param endpoint {@link ZigBeeEndpoint} the device that we want to bound to
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,6 @@ public interface ZigBeeNode {
/**
* @return a {@link String} representing the IEEEAddress of the node
*/
public String getIEEEAddress();
public String getIeeeAddress();

}
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ public void task() {
} catch (Exception e) {
e.printStackTrace();
}
logger.trace("Network browsing completed, waiting until {}", wakeUpTime);
logger.debug("Network browsing completed, waiting until {}", wakeUpTime);
initialNetworkBrowsingComplete = true;
if (!isDone()) ThreadUtils.waitingUntil(wakeUpTime);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ private boolean inspectEndpointOfNode(final int nwkAddress, final ZigBeeNode nod
private void doCreateZigBeeEndpoint(ZigBeeNode node, short ep) {
final ZigBeeNetwork network = ApplicationFrameworkLayer.getAFLayer(driver).getZigBeeNetwork();
synchronized (network) {
if (network.containsEndpoint(node.getIEEEAddress(), ep)) {
if (network.containsEndpoint(node.getIeeeAddress(), ep)) {
logger.info(
"Skipping device creation for endpoint {} on node {} as it is created.", ep, node
);
Expand Down Expand Up @@ -181,14 +181,12 @@ private void inspectNode(ZToolAddress16 nwkAddress, ZToolAddress64 ieeeAddress)
boolean isNew = false, correctlyInspected = false;
final ZigBeeNetwork network = ApplicationFrameworkLayer.getAFLayer(driver).getZigBeeNetwork();
synchronized (network) {
node = network.containsNode(ieee);
node = network.getNode(ieee);
if (node == null) {
node = new ZigBeeNodeImpl(nwk, ieeeAddress, (short) driver.getCurrentPanId());
isNew = true;
network.addNode(node);
logger.debug("Created node object for {} that was not available on the network", node);
} else {

}
}
if (isNew) {
Expand All @@ -213,7 +211,7 @@ private void inspectNode(ZToolAddress16 nwkAddress, ZToolAddress64 ieeeAddress)
* No previous device inspection completed successfully, so we should try to inspect
* the device again
*/
inspectEndpointOfNode(nwk, new ZigBeeNodeImpl(nwk, node.getIEEEAddress(), (short) driver.getCurrentPanId()));
inspectEndpointOfNode(nwk, new ZigBeeNodeImpl(nwk, node.getIeeeAddress(), (short) driver.getCurrentPanId()));
}
node.setNetworkAddress(nwk);
}
Expand All @@ -240,11 +238,10 @@ private boolean changedNetworkAddress(ZigBeeNodeImpl node, int nwk) {
private void inspectNewEndpoint() {
nextInspectionSlot = 10 + System.currentTimeMillis();
final ImportingQueue.ZigBeeNodeAddress dev = queue.pop();
inspectingNewEndpoint = true;
if (dev == null) {
inspectingNewEndpoint = false;
return;
}
inspectingNewEndpoint = true;
final ZToolAddress16 nwk = dev.getNetworkAddress();
final ZToolAddress64 ieee = dev.getIEEEAddress();
logger.debug("Inspecting device {}.", IEEEAddress.toString(ieee.getLong()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ private List<NetworkAddressNodeItem> lqiRequestToNode(NetworkAddressNodeItem nod
NetworkAddressNodeItem result = getIEEEAddress((short) neighbor.NetworkAddress.get16BitValue());
NetworkAddressNodeItem newNode;
if (result != null) {
logger.debug("Node #{} is {}", new Object[]{neighbor.NetworkAddress.get16BitValue(), result.node.getIEEEAddress()});
logger.debug("Node #{} is {}", new Object[]{neighbor.NetworkAddress.get16BitValue(), result.node.getIeeeAddress()});
newNode = new NetworkAddressNodeItem(node, result.address);
connectedNodesFound.add(newNode);
} else {
Expand Down Expand Up @@ -251,7 +251,7 @@ public void task() {

long wakeUpTime = System.currentTimeMillis() + 5 * 60 * 1000;
if (!isDone()) ThreadUtils.waitingUntil(wakeUpTime);
logger.info("Network browsing completed, waiting until {}", wakeUpTime);
logger.debug("Network browsing completed, waiting until {}", wakeUpTime);
//gt.run();
} catch (Exception e) {
e.printStackTrace();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,17 +154,17 @@ public void run() {
* @param sourceNetworkAddress the network address to inspect
*/
private synchronized void inspectNetworkAddress(final int sourceNetworkAddress) {
logger.info("Inspecting node based on incoming AF message from network address #{}.",
logger.debug("Inspecting node based on incoming AF message from network address #{}.",
sourceNetworkAddress);

final ZDO_IEEE_ADDR_RSP result = networkManager.sendZDOIEEEAddressRequest(
new ZDO_IEEE_ADDR_REQ(sourceNetworkAddress, ZDO_IEEE_ADDR_REQ.REQ_TYPE.SINGLE_DEVICE_RESPONSE, (byte) 0)
);

if (result == null) {
logger.info("Node did not respond to ZDO_IEEE_ADDR_REQ #{}", sourceNetworkAddress);
logger.debug("Node did not respond to ZDO_IEEE_ADDR_REQ #{}", sourceNetworkAddress);
} else if (result.Status == 0) {
logger.info("Node network address #{} resolved to IEEE address {}.", sourceNetworkAddress, result.getIEEEAddress());
logger.debug("Node network address #{} resolved to IEEE address {}.", sourceNetworkAddress, result.getIEEEAddress());
final ZigBeeNodeImpl node = new ZigBeeNodeImpl(sourceNetworkAddress, result.getIEEEAddress(),
(short) networkManager.getCurrentPanId());

Expand All @@ -177,7 +177,7 @@ private synchronized void inspectNetworkAddress(final int sourceNetworkAddress)
final ZigBeeNetwork network = ApplicationFrameworkLayer.getAFLayer(networkManager).getZigBeeNetwork();
network.notifyNodeBrowsed(node);
} else {
logger.info("Node #{} ZDO_IEEE_ADDR_REQ failed with status {} ", sourceNetworkAddress,
logger.warn("Node #{} ZDO_IEEE_ADDR_REQ failed with status {} ", sourceNetworkAddress,
Status.getStatus((byte) result.Status));
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package org.bubblecloud.zigbee.network.impl;

import org.bubblecloud.zigbee.network.ZigBeeEndpoint;
import org.bubblecloud.zigbee.network.ZigBeeNetworkManager;
import org.bubblecloud.zigbee.network.ZigBeeNode;
import org.codehaus.jackson.map.ObjectMapper;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
* NetworkStateSerializer serializes and deserializes the ZigBeeNetworkState.
*/
public class NetworkStateSerializer {

/**
* Serializes network state.
* @return the serialized network state as String.
*/
public String serialize(final ZigBeeNetwork zigBeeNetwork) {
final ObjectMapper objectMapper = new ObjectMapper();
objectMapper.enableDefaultTyping();
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
try {
final HashMap<ZigBeeNode, HashMap<Integer, ZigBeeEndpoint>> devices = new HashMap(zigBeeNetwork.getDevices());

final List<ZigBeeEndpoint> endpoints = new ArrayList<ZigBeeEndpoint>();
for (final ZigBeeNode node : devices.keySet()) {
for (final ZigBeeEndpoint endpoint : devices.get(node).values()) {
endpoints.add(endpoint);
}
}

return objectMapper.writeValueAsString(endpoints);
} catch (final IOException e) {
throw new RuntimeException("Error serializing network state.", e);
}
}

/**
* Deserializes network state.
* @param zigBeeNetworkManager the ZigBee network manager
* @param zigBeeNetwork the ZigBee network
* @param networkStateString the network state as String
*/
public void deserialize(final ZigBeeNetworkManager zigBeeNetworkManager, final ZigBeeNetwork zigBeeNetwork, final String networkStateString) {
final ObjectMapper objectMapper = new ObjectMapper();
objectMapper.enableDefaultTyping();
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
final List<ZigBeeEndpoint> endpoints;
try {
endpoints = objectMapper.readValue(networkStateString, ArrayList.class);
} catch (final IOException e) {
throw new RuntimeException("Error serializing network state.", e);
}
for (final ZigBeeEndpoint endpoint : endpoints) {
if (zigBeeNetwork.getNode(endpoint.getNode().getIeeeAddress()) == null) {
zigBeeNetwork.addNode((ZigBeeNodeImpl) endpoint.getNode());
}
((ZigBeeEndpointImpl) endpoint).setNetworkManager(zigBeeNetworkManager);
zigBeeNetwork.addEndpoint(endpoint);
}
}

}
Loading

0 comments on commit 01909c0

Please sign in to comment.