1 package iotcode.MultipurposeSensor;
3 // Standard Java Packages
5 import java.util.concurrent.atomic.AtomicBoolean;
6 import java.util.concurrent.CopyOnWriteArrayList;
7 import java.util.concurrent.Semaphore;
10 import iotcode.annotation.*;
11 import iotruntime.slave.*;
12 import iotcode.interfaces.*;
13 import iotruntime.zigbee.*;
15 /** Class Smartthings sensor driver for Smartthings sensor devices.
17 * @author Changwoo Lee, Rahmadi Trimananda <rtrimana @ uci.edu>
21 public class MultipurposeSensor implements IoTZigbeeCallback, SmartthingsSensor {
23 private final int TIMEOUT_FOR_RESEND_MSEC = 900;
25 private IoTZigbee zigConnection = null;
26 private boolean didClose; // make sure that the clean up was done correctly
27 private boolean detectStatus = false;
29 private int detectedValue = 0;
30 private Date timestampOfLastDetecting = null;
32 private AtomicBoolean didAlreadyClose = new AtomicBoolean(true);
33 private AtomicBoolean didAlreadyInit = new AtomicBoolean(false);
34 private AtomicBoolean didWriteAttrb = new AtomicBoolean(false);
35 private AtomicBoolean didMatchDscr = new AtomicBoolean(false);
36 static Semaphore gettingLatestDataMutex = new Semaphore(1);
38 private List < SmartthingsSensorSmartCallback > callbackList = new CopyOnWriteArrayList < SmartthingsSensorSmartCallback > ();
40 private int sensorId = 0;
42 @config private IoTSet<IoTDeviceAddress> multipurposeSensorUdpAddress;
43 @config private IoTSet<IoTZigbeeAddress> multipurposeSensorZigbeeAddress;
45 // TODO: Test constructor
46 //public MultipurposeSensor(IoTSet<IoTDeviceAddress> dSet, IoTSet<IoTZigbeeAddress> zigSet) {
47 //multipurposeSensorUdpAddress = dSet;
48 //multipurposeSensorZigbeeAddress = zigSet;
50 public MultipurposeSensor() {
55 if (didAlreadyInit.compareAndSet(false, true) == false) {
56 return; // already init
58 didAlreadyClose.set(false);
61 Iterator itrUdp = multipurposeSensorUdpAddress.iterator();
62 Iterator itrZig = multipurposeSensorZigbeeAddress.iterator();
64 zigConnection = new IoTZigbee((IoTDeviceAddress)itrUdp.next(), (IoTZigbeeAddress)itrZig.next());
67 System.out.println("DEBUG: Allocate iterators to print out addresses!");
68 Iterator itrDebugUdp = multipurposeSensorUdpAddress.iterator();
69 IoTDeviceAddress iotaddDebug = (IoTDeviceAddress)itrDebugUdp.next();
70 System.out.println("IP address: " + iotaddDebug.getCompleteAddress());
71 System.out.println("Source port: " + iotaddDebug.getSourcePortNumber());
72 System.out.println("Destination port: " + iotaddDebug.getDestinationPortNumber());
74 Iterator itrDebugZig = multipurposeSensorZigbeeAddress.iterator();
75 IoTZigbeeAddress iotzbaddDebug = (IoTZigbeeAddress)itrDebugZig.next();
76 System.out.println("Zigbee address: " + iotzbaddDebug.getAddress());
78 zigConnection.registerCallback(this);
79 System.out.println("Register callback!");
81 System.out.println("Initialized!");
85 System.out.println("Sending Management Permit Joining Request");
86 for(int z=0; z<3; z++){
87 zigConnection.sendManagementPermitJoiningRequest(0x0001, 0x0036, 0x00);
92 while (!didWriteAttrb.get()) {
93 System.out.println("Sending Write Attribute Request");
94 zigConnection.sendWriteAttributesCommand(0x0002, 0x0500, 0x0104, 0x01);
99 System.out.println("Sending Enrollment Reponse");
100 zigConnection.sendEnrollmentResponse(0x0003, 0x0500, 0x0104, 0x01);
103 } catch (Exception e) {
109 private void sleep(int multipleTime){
114 Thread.sleep(TIMEOUT_FOR_RESEND_MSEC*multipleTime);
115 } catch(Exception e){
120 public void close() {
122 if (didAlreadyClose.compareAndSet(false, true) == false) {
123 return; // already init
126 didAlreadyInit.set(false);
130 zigConnection.close();
131 } catch (Exception e) {
136 public void Finalize() {
142 public void setId(int id) {
154 public int getValue() {
158 gettingLatestDataMutex.acquire();
161 } catch (Exception e) {
164 gettingLatestDataMutex.release();
169 // MultipurposeSensor:
170 // - 24 = close = false
171 // - 25 = open = true
172 public boolean isActiveValue() {
174 int tmp = getValue();
177 else // Getting 24 here
178 detectStatus = false;
183 public long getTimestampOfLastReading() {
187 gettingLatestDataMutex.acquire();
188 tmp = (Date)timestampOfLastDetecting.clone();
190 } catch (Exception e) {
193 gettingLatestDataMutex.release();
194 long retLong = tmp.getTime();
199 public void newMessageAvailable(IoTZigbeeMessage _zm) {
202 if(_zm instanceof IoTZigbeeMessageZclZoneStatusChangeNotification){
203 IoTZigbeeMessageZclZoneStatusChangeNotification message = (IoTZigbeeMessageZclZoneStatusChangeNotification)_zm;
204 if(message.getSuccessOrFail()){
207 gettingLatestDataMutex.acquire();
208 detectedValue = message.getStatus();
209 timestampOfLastDetecting = new Date();
210 } catch (Exception e) {
213 gettingLatestDataMutex.release();
215 for (SmartthingsSensorSmartCallback cb : callbackList) {
216 cb.newReadingAvailable(this.getId(), this.getValue(), this.isActiveValue());
218 } catch (Exception e) {
225 else if (_zm instanceof IoTZigbeeMessageZclWriteAttributesResponse) {
226 IoTZigbeeMessageZclWriteAttributesResponse message = (IoTZigbeeMessageZclWriteAttributesResponse)_zm;
227 if (message.getSuccessOrFail()) {
228 didWriteAttrb.set(true);
233 public void registerCallback(SmartthingsSensorSmartCallback _callbackTo) {
234 callbackList.add(_callbackTo);