1 // Standard Java Packages
2 import java.util.Iterator;
4 import java.util.ArrayList;
6 import java.util.concurrent.atomic.AtomicBoolean;
7 import java.util.concurrent.CopyOnWriteArrayList;
8 import java.util.concurrent.Semaphore;
11 // Checker annotations
12 //import iotchecker.qual.*;
15 import iotruntime.slave.*;
16 //import iotcode.interfaces.MoistureSensor;
17 //import iotcode.interfaces.MoistureSensorSmartCallback;
18 import iotruntime.zigbee.*;
19 //import iotcode.annotation.*;
21 public class SpruceSensor implements IoTZigbeeCallback, MoistureSensor {
23 private final int TIMEOUT_FOR_RESEND_MSEC = 1000;
25 private IoTZigbee zigConnection = null;
26 private boolean didClose; // make sure that the clean up was done correctly
28 private float humidity = 0;
29 private Date timestampOfLastHumidity = null;
31 private AtomicBoolean didBind = new AtomicBoolean(false);
32 private AtomicBoolean didConfigureReporting = new AtomicBoolean(false);
33 private AtomicBoolean didAlreadyInit = new AtomicBoolean(false);
34 private AtomicBoolean didAlreadyClose = new AtomicBoolean(true);
35 static Semaphore gettingLatestDataMutex = new Semaphore(1);
37 private List < MoistureSensorSmartCallback > callbackList = new CopyOnWriteArrayList < MoistureSensorSmartCallback > ();
39 private int sensorId = 0;
41 @config private IoTSet<IoTDeviceAddress> devUdpAddress;
42 @config private IoTSet<IoTZigbeeAddress> devZigbeeAddress;
44 public SpruceSensor(IoTSet<IoTDeviceAddress> _devUdpAddress, IoTSet<IoTZigbeeAddress> _devZigbeeAddress) {
45 devUdpAddress = _devUdpAddress;
46 devZigbeeAddress = _devZigbeeAddress;
51 if (didAlreadyInit.compareAndSet(false, true) == false) {
52 return; // already init
55 didAlreadyClose.set(false);
58 Iterator itrUdp = devUdpAddress.iterator();
59 Iterator itrZig = devZigbeeAddress.iterator();
61 zigConnection = new IoTZigbee((IoTDeviceAddress)itrUdp.next(), (IoTZigbeeAddress)itrZig.next());
64 System.out.println("DEBUG: Allocate iterators to print out addresses!");
65 Iterator itrDebugUdp = devUdpAddress.iterator();
66 IoTDeviceAddress iotaddDebug = (IoTDeviceAddress)itrDebugUdp.next();
67 System.out.println("IP address: " + iotaddDebug.getCompleteAddress());
68 System.out.println("Source port: " + iotaddDebug.getSourcePortNumber());
69 System.out.println("Destination port: " + iotaddDebug.getDestinationPortNumber());
71 Iterator itrDebugZig = devZigbeeAddress.iterator();
72 IoTZigbeeAddress iotzbaddDebug = (IoTZigbeeAddress)itrDebugZig.next();
73 System.out.println("Zigbee address: " + iotzbaddDebug.getAddress());
75 zigConnection.registerCallback(this);
76 System.out.println("Register callback!");
78 System.out.println("Initialized!");
80 while (!didBind.get()) {
81 zigConnection.sendBindRequest(0x0001, 0x0405, 0x01);
83 Thread.sleep(TIMEOUT_FOR_RESEND_MSEC);
84 } catch (Exception e) {
89 while (!didConfigureReporting.get()) {
90 zigConnection.sendConfigureReportingCommand(0x0001, 0x0405, 0x0104, 0x01, 0x0000, 0x21, 0x0001, 0x0001, null);
92 Thread.sleep(TIMEOUT_FOR_RESEND_MSEC);
93 } catch (Exception e) {
97 } catch (Exception e) {
102 public void close() {
104 if (didAlreadyClose.compareAndSet(false, true) == false) {
105 return; // already init
108 didAlreadyInit.set(false);
112 zigConnection.close();
113 } catch (Exception e) {
118 public void Finalize() {
124 public void setId(int id) {
136 public float getMoisture() {
140 gettingLatestDataMutex.acquire();
143 } catch (Exception e) {
146 gettingLatestDataMutex.release();
151 public long getTimestampOfLastReading() {
155 gettingLatestDataMutex.acquire();
156 tmp = (Date)timestampOfLastHumidity.clone();
158 } catch (Exception e) {
161 gettingLatestDataMutex.release();
162 long retLong = tmp.getTime();
167 public void newMessageAvailable(IoTZigbeeMessage _zm) {
169 if (_zm instanceof IoTZigbeeMessageZdoBindResponse) {
170 IoTZigbeeMessageZdoBindResponse message = (IoTZigbeeMessageZdoBindResponse)_zm;
171 if (message.getSucceeded()) {
175 } else if (_zm instanceof IoTZigbeeMessageZclConfigureReportingResponse) {
176 IoTZigbeeMessageZclConfigureReportingResponse message = (IoTZigbeeMessageZclConfigureReportingResponse)_zm;
177 if (message.getAllSuccess()) {
178 didConfigureReporting.set(true);
181 } else if (_zm instanceof IoTZigbeeMessageZclReportAttributes) {
182 IoTZigbeeMessageZclReportAttributes message = (IoTZigbeeMessageZclReportAttributes)_zm;
183 List <IoTZigbeeMessageZclReportAttributes.Attribute> attrList = message.getAttributes();
185 if (attrList.size() == 1) {
186 if (attrList.get(0).getAttributeId() == 0) {
187 byte[] data = attrList.get(0).getData();
189 int value = (data[0] * 256) + data[1];
192 gettingLatestDataMutex.acquire();
193 humidity = (float)value / (float)100.0;
194 timestampOfLastHumidity = new Date();
195 } catch (Exception e) {
198 gettingLatestDataMutex.release();
201 for (MoistureSensorSmartCallback cb : callbackList) {
202 cb.newReadingAvailable(this.getId(), this.getMoisture(), this.getTimestampOfLastReading());
204 } catch (Exception e) {
213 public void registerCallback(MoistureSensorSmartCallback _callbackTo) {
214 callbackList.add(_callbackTo);