1 package iotcode.SpruceSensor;
3 // Standard Java Packages
4 import java.util.Iterator;
6 import java.util.ArrayList;
8 import java.util.concurrent.atomic.AtomicBoolean;
9 import java.util.concurrent.CopyOnWriteArrayList;
10 import java.util.concurrent.Semaphore;
13 // Checker annotations
14 //import iotchecker.qual.*;
17 import iotruntime.slave.*;
18 import iotcode.interfaces.MoistureSensor;
19 import iotcode.interfaces.MoistureSensorSmartCallback;
20 import iotruntime.zigbee.*;
21 import iotcode.annotation.*;
23 public class SpruceSensor implements IoTZigbeeCallback, MoistureSensor {
25 private final int TIMEOUT_FOR_RESEND_MSEC = 1000;
27 private IoTZigbee zigConnection = null;
28 private boolean didClose; // make sure that the clean up was done correctly
30 private float humidity = 0;
31 private Date timestampOfLastHumidity = null;
33 private AtomicBoolean didBind = new AtomicBoolean(false);
34 private AtomicBoolean didConfigureReporting = new AtomicBoolean(false);
35 private AtomicBoolean didAlreadyInit = new AtomicBoolean(false);
36 private AtomicBoolean didAlreadyClose = new AtomicBoolean(true);
37 static Semaphore gettingLatestDataMutex = new Semaphore(1);
39 private List < MoistureSensorSmartCallback > callbackList = new CopyOnWriteArrayList < MoistureSensorSmartCallback > ();
41 private int sensorId = 0;
43 @config private IoTSet<IoTDeviceAddress> devUdpAddress;
44 @config private IoTSet<IoTZigbeeAddress> devZigbeeAddress;
46 public SpruceSensor() {
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);