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