09eb5398b5e9dca50930508fb28a94c3d7867363
[iot2.git] / benchmarks / drivers / Java / DoorlockActuator / DoorlockActuator.java
1 package iotcode.DoorlockActuator;
2
3 // Standard Java Packages
4 import java.util.*;
5 import java.util.concurrent.atomic.AtomicBoolean;
6 import java.util.concurrent.CopyOnWriteArrayList;
7 import java.util.concurrent.Semaphore;
8
9 // Checker annotations
10 //import iotchecker.qual.*;
11 import iotcode.annotation.*;
12
13 // IoT Packages
14 import iotruntime.slave.*;
15 import iotcode.interfaces.*;
16 import iotruntime.zigbee.*;
17
18 /** Class Smartthings sensor driver for Smartthings sensor devices.
19  *
20  * @author      Changwoo Lee, Rahmadi Trimananda <rtrimana @ uci.edu>
21  * @version     1.0
22  * @since       2016-12-01
23  */
24 public class DoorlockActuator implements IoTZigbeeCallback, SmartthingsActuator {
25
26         private final int TIMEOUT_FOR_RESEND_MSEC = 900;
27
28         private IoTZigbee zigConnection = null;
29         private boolean didClose; // make sure that the clean up was done correctly
30         private boolean detectStatus = false;
31
32         private int detectedValue = 0;
33         private Date timestampOfLastDetecting = null;
34
35         private AtomicBoolean didAlreadyClose = new AtomicBoolean(true);
36         private AtomicBoolean didAlreadyInit = new AtomicBoolean(false);
37         private AtomicBoolean didWriteAttrb = new AtomicBoolean(false);
38         private AtomicBoolean didMatchDscr = new AtomicBoolean(false);
39         private AtomicBoolean didBind = new AtomicBoolean(false);
40         private AtomicBoolean didDoorLockConfigureReporting = new AtomicBoolean(false); //made by Jiawei
41         static Semaphore gettingLatestDataMutex = new Semaphore(1);
42
43         private List < SmartthingsActuatorSmartCallback > callbackList = new CopyOnWriteArrayList < SmartthingsActuatorSmartCallback > ();
44
45         private int sensorId = 0;
46
47         @config private IoTSet<IoTDeviceAddress> doorlockActuatorUdpAddress;
48         @config private IoTSet<IoTZigbeeAddress> doorlockActuatorZigbeeAddress;
49
50         public DoorlockActuator(IoTSet<IoTDeviceAddress> dSet, IoTSet<IoTZigbeeAddress> zigSet) {
51                 doorlockActuatorUdpAddress = dSet;
52                 doorlockActuatorZigbeeAddress = zigSet;
53         }
54
55         public DoorlockActuator() {
56         }
57
58         public void init() {
59
60                 if (didAlreadyInit.compareAndSet(false, true) == false) {
61                         return; // already init
62                 }
63
64                 didAlreadyClose.set(false);
65
66                 try {
67                         Iterator itrUdp = doorlockActuatorUdpAddress.iterator();
68                         Iterator itrZig = doorlockActuatorZigbeeAddress.iterator();
69
70                         zigConnection = new IoTZigbee((IoTDeviceAddress)itrUdp.next(), (IoTZigbeeAddress)itrZig.next());
71
72                         // DEBUG
73                         System.out.println("DEBUG: Allocate iterators to print out addresses!");
74                         Iterator itrDebugUdp = doorlockActuatorUdpAddress.iterator();
75                         IoTDeviceAddress iotaddDebug = (IoTDeviceAddress)itrDebugUdp.next();
76                         System.out.println("IP address: " + iotaddDebug.getCompleteAddress());
77                         System.out.println("Source port: " + iotaddDebug.getSourcePortNumber());
78                         System.out.println("Destination port: " + iotaddDebug.getDestinationPortNumber());
79
80                         Iterator itrDebugZig = doorlockActuatorZigbeeAddress.iterator();
81                         IoTZigbeeAddress iotzbaddDebug = (IoTZigbeeAddress)itrDebugZig.next();
82                         System.out.println("Zigbee address: " + iotzbaddDebug.getAddress());
83
84                         zigConnection.registerCallback(this);
85                         System.out.println("Register callback!");
86                         zigConnection.init();
87                         System.out.println("Initialized!");
88
89
90             
91                         //made by changwoo
92                         sleep(10);
93
94             // System.out.println("BroadcastingRouteRecordRequest ");
95                         // zigConnection.sendBroadcastingRouteRecordRequest(0x0001);
96             // sleep(6);
97
98                         System.out.println("Sending Management Permit Joining Request");
99                         // for(int z=0; z<3; z++){
100                                 zigConnection.sendManagementPermitJoiningRequest(0x0002, 0x0036, 0x00);
101                                 sleep(0);
102                         // }
103
104
105             while(!didBind.get()){
106                                 System.out.println("Sending Bind Request");
107                                 zigConnection.sendBindRequest(0x0003, 0x0101, 0x02);
108                                 sleep(0);
109                         }
110                         
111                         while(!didDoorLockConfigureReporting.get()){
112                                 System.out.println("Sending Door Lock: Configure Reporting");
113                                 zigConnection.sendConfigureReportingCommand(0x0004, 0x0101, 0x0104, 0x01, 0x02, 0x0000, 0x30, 0x0000, 0x100E, null);
114                                 sleep(0);
115                         }
116
117                 } catch (Exception e) {
118                         e.printStackTrace();
119                 }
120         }
121
122         /**
123          * actuate() method
124          *
125          * @param   value       Integer value for actuation
126          * @return  boolean Status of sending actuate command
127          */
128         public boolean actuate(int value) {
129
130                 // Value check
131                 if (value == 0)
132                         System.out.println("Doorlock: Is locking!");
133                 else if(value == 1)
134                         System.out.println("Doorlock: Is unlocking!");
135                 else { // Failed to send command because of invalid value
136                         throw new Error("Doorlock: Actuate value " + value + " is not recognized (only 0 or 1)! Please check your method call...");
137                 }
138                 try {
139                         zigConnection.sendLockOrUnlockDoorRequest(0x0005, 0x0101, 0x0104, 0x02, value);
140                         sleep(0);
141                 } catch (Exception e) {
142                         e.printStackTrace();
143                 }
144                 return true;
145         }
146
147         /**
148          * requestStatus() method
149          *
150          * @return  void
151          */
152         public void requestStatus() {
153                 System.out.println("Doorlock: Requesting status... Receiving answer through callback...");
154                 try {
155                         zigConnection.sendReadDoorStatusRequest(0x0005, 0x0101, 0x0104, 0x02, 0x10, 0x00, 0x0000);
156                         sleep(0);
157                 } catch (Exception e) {
158                         e.printStackTrace();
159                 }
160         }
161
162         //made by changwoo
163         private void sleep(int multipleTime){
164                 if(multipleTime<=0){
165                         multipleTime=1;
166                 }
167                 try{
168                         Thread.sleep(TIMEOUT_FOR_RESEND_MSEC*multipleTime);
169                 } catch(Exception e){
170                         e.printStackTrace();
171                 }
172         }
173
174         // made by Jiawei
175     public int getStatus() {
176
177                 int tmp = 0;
178
179                 try {
180                         gettingLatestDataMutex.acquire();
181                         tmp = detectedValue;
182
183                 } catch (Exception e) {
184                         e.printStackTrace();
185                 }
186                 gettingLatestDataMutex.release();
187
188                 return tmp;
189         }
190
191         public boolean isActiveStatus() {
192
193                 int tmp = getStatus();
194                 if (tmp == 1)
195                         detectStatus = true;    // ACTIVE == Door is locked
196                 else
197                         detectStatus = false;   // NOT ACTIVE == Door is not locked/not fully locked
198                 return detectStatus;
199         }
200
201         public void close() {
202
203                 if (didAlreadyClose.compareAndSet(false, true) == false) {
204                         return; // already init
205                 }
206
207                 didAlreadyInit.set(false);
208
209
210                 try {
211                         zigConnection.close();
212                 } catch (Exception e) {
213                         e.printStackTrace();
214                 }
215         }
216
217         public void Finalize() {
218                 if (!didClose) {
219                         close();
220                 }
221         }
222
223         public void setId(int id) {
224
225                 sensorId = id;
226
227         }
228
229         public int getId() {
230
231                 return sensorId;
232
233         }
234
235
236         public long getTimestampOfLastReading() {
237
238                 Date tmp = null;
239                 try {
240                         gettingLatestDataMutex.acquire();
241                         tmp = (Date)timestampOfLastDetecting.clone();
242
243                 } catch (Exception e) {
244                         e.printStackTrace();
245                 }
246                 gettingLatestDataMutex.release();
247                 long retLong = tmp.getTime();
248
249                 return retLong;
250         }
251
252         public void newMessageAvailable(IoTZigbeeMessage _zm) {
253                 
254                 //made by yuting
255                 if (_zm instanceof IoTZigbeeMessageZdoBindResponse) {
256                         IoTZigbeeMessageZdoBindResponse message = (IoTZigbeeMessageZdoBindResponse)_zm;
257                         if (message.getSucceeded()) {
258                                 didBind.set(true);
259                         }
260                 }
261                 else if (_zm instanceof IoTZigbeeMessageZclConfigureReportingResponse){
262                         IoTZigbeeMessageZclConfigureReportingResponse message = (IoTZigbeeMessageZclConfigureReportingResponse)_zm;
263                         if (message.getAllSuccess()) {
264                                 didDoorLockConfigureReporting.set(true);
265                         }
266                 }
267                 else if (_zm instanceof IoTZigbeeMessageZclReadAttributesResponse) {
268                         IoTZigbeeMessageZclReadAttributesResponse message = (IoTZigbeeMessageZclReadAttributesResponse)_zm;
269                         List <IoTZigbeeMessageZclReadAttributesResponse.Attribute> attrList = message.getAttributes();
270
271                         if (attrList.size() == 1) {
272                                 if(attrList.get(0).getAttributeId() == 0) {
273                                         byte[] data = attrList.get(0).getData();
274                                         int value = data[0];
275
276                                         try {
277                                                 gettingLatestDataMutex.acquire();
278                                                 detectedValue = value;
279                                                 timestampOfLastDetecting = new Date();
280                                         } catch (Exception e) {
281                                                 e.printStackTrace();
282                                         }
283                                         gettingLatestDataMutex.release();
284
285                                         try {
286                                                 for (SmartthingsActuatorSmartCallback cb : callbackList) {
287                                                         cb.newActuatorReadingAvailable(this.getId(), this.getStatus(), this.isActiveStatus());
288                                                 }
289                                         } catch (Exception e) {
290                                                 e.printStackTrace();
291                                         }
292                                 }       
293                         }
294                 }
295         }
296
297         public void registerCallback(SmartthingsActuatorSmartCallback _callbackTo) {
298                 callbackList.add(_callbackTo);
299         }
300 }